aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0510-drm-amd-dal-Add-dal-display-driver.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0510-drm-amd-dal-Add-dal-display-driver.patch')
-rw-r--r--common/recipes-kernel/linux/files/0510-drm-amd-dal-Add-dal-display-driver.patch90113
1 files changed, 0 insertions, 90113 deletions
diff --git a/common/recipes-kernel/linux/files/0510-drm-amd-dal-Add-dal-display-driver.patch b/common/recipes-kernel/linux/files/0510-drm-amd-dal-Add-dal-display-driver.patch
deleted file mode 100644
index 1606a1aa..00000000
--- a/common/recipes-kernel/linux/files/0510-drm-amd-dal-Add-dal-display-driver.patch
+++ /dev/null
@@ -1,90113 +0,0 @@
-From 35eea4f1b20ded08fc0d65891163d03238e3adf6 Mon Sep 17 00:00:00 2001
-From: Harry Wentland <harry.wentland@amd.com>
-Date: Wed, 25 Nov 2015 14:45:50 -0500
-Subject: [PATCH 0510/1110] drm/amd/dal: Add dal display driver
-
-Signed-off-by: Harry Wentland <harry.wentland@amd.com>
-Acked-by: Alex Deucher <alexander.deucher@amd.com>
----
- drivers/gpu/drm/amd/dal/Kconfig | 39 +
- drivers/gpu/drm/amd/dal/Makefile | 19 +
- .../gpu/drm/amd/dal/dal_power_interface_types.h | 76 +
- drivers/gpu/drm/amd/dal/dal_services.h | 266 ++
- drivers/gpu/drm/amd/dal/dal_services_types.h | 62 +
- drivers/gpu/drm/amd/dal/dc/Makefile | 24 +
- drivers/gpu/drm/amd/dal/dc/adapter/Makefile | 18 +
- .../gpu/drm/amd/dal/dc/adapter/adapter_service.c | 2037 +++++++++
- .../gpu/drm/amd/dal/dc/adapter/adapter_service.h | 67 +
- .../adapter/dce110/hw_ctx_adapter_service_dce110.c | 303 ++
- .../adapter/dce110/hw_ctx_adapter_service_dce110.h | 40 +
- .../amd/dal/dc/adapter/hw_ctx_adapter_service.c | 164 +
- .../amd/dal/dc/adapter/hw_ctx_adapter_service.h | 86 +
- .../drm/amd/dal/dc/adapter/wireless_data_source.c | 209 +
- .../drm/amd/dal/dc/adapter/wireless_data_source.h | 80 +
- .../gpu/drm/amd/dal/dc/asic_capability/Makefile | 23 +
- .../amd/dal/dc/asic_capability/asic_capability.c | 178 +
- .../dc/asic_capability/carrizo_asic_capability.c | 146 +
- .../dc/asic_capability/carrizo_asic_capability.h | 36 +
- drivers/gpu/drm/amd/dal/dc/audio/Makefile | 22 +
- drivers/gpu/drm/amd/dal/dc/audio/audio.h | 195 +
- drivers/gpu/drm/amd/dal/dc/audio/audio_base.c | 463 ++
- .../gpu/drm/amd/dal/dc/audio/dce110/audio_dce110.c | 452 ++
- .../gpu/drm/amd/dal/dc/audio/dce110/audio_dce110.h | 42 +
- .../amd/dal/dc/audio/dce110/hw_ctx_audio_dce110.c | 1929 ++++++++
- .../amd/dal/dc/audio/dce110/hw_ctx_audio_dce110.h | 47 +
- drivers/gpu/drm/amd/dal/dc/audio/hw_ctx_audio.c | 771 ++++
- drivers/gpu/drm/amd/dal/dc/audio/hw_ctx_audio.h | 285 ++
- drivers/gpu/drm/amd/dal/dc/basics/Makefile | 10 +
- drivers/gpu/drm/amd/dal/dc/basics/conversion.c | 223 +
- drivers/gpu/drm/amd/dal/dc/basics/conversion.h | 49 +
- drivers/gpu/drm/amd/dal/dc/basics/fixpt31_32.c | 692 +++
- drivers/gpu/drm/amd/dal/dc/basics/fixpt32_32.c | 223 +
- drivers/gpu/drm/amd/dal/dc/basics/grph_object_id.c | 135 +
- drivers/gpu/drm/amd/dal/dc/basics/logger.c | 947 ++++
- drivers/gpu/drm/amd/dal/dc/basics/logger.h | 64 +
- .../gpu/drm/amd/dal/dc/basics/register_logger.c | 197 +
- drivers/gpu/drm/amd/dal/dc/basics/signal_types.c | 116 +
- drivers/gpu/drm/amd/dal/dc/basics/vector.c | 309 ++
- drivers/gpu/drm/amd/dal/dc/bios/Makefile | 27 +
- drivers/gpu/drm/amd/dal/dc/bios/bios_parser.c | 4758 ++++++++++++++++++++
- drivers/gpu/drm/amd/dal/dc/bios/bios_parser.h | 78 +
- .../gpu/drm/amd/dal/dc/bios/bios_parser_helper.c | 193 +
- .../gpu/drm/amd/dal/dc/bios/bios_parser_helper.h | 108 +
- drivers/gpu/drm/amd/dal/dc/bios/command_table.c | 2616 +++++++++++
- drivers/gpu/drm/amd/dal/dc/bios/command_table.h | 117 +
- .../gpu/drm/amd/dal/dc/bios/command_table_helper.c | 315 ++
- .../gpu/drm/amd/dal/dc/bios/command_table_helper.h | 87 +
- .../dal/dc/bios/dce110/bios_parser_helper_dce110.c | 484 ++
- .../dal/dc/bios/dce110/bios_parser_helper_dce110.h | 34 +
- .../dc/bios/dce110/command_table_helper_dce110.c | 369 ++
- .../dc/bios/dce110/command_table_helper_dce110.h | 34 +
- drivers/gpu/drm/amd/dal/dc/calcs/Makefile | 10 +
- drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c | 3478 ++++++++++++++
- drivers/gpu/drm/amd/dal/dc/calcs/bw_fixed.c | 278 ++
- drivers/gpu/drm/amd/dal/dc/calcs/scaler_filter.c | 1992 ++++++++
- drivers/gpu/drm/amd/dal/dc/calcs/scaler_filter.h | 74 +
- drivers/gpu/drm/amd/dal/dc/connector/Makefile | 10 +
- drivers/gpu/drm/amd/dal/dc/connector/connector.h | 39 +
- .../gpu/drm/amd/dal/dc/connector/connector_base.c | 421 ++
- .../drm/amd/dal/dc/connector/connector_signals.c | 204 +
- drivers/gpu/drm/amd/dal/dc/core/dc.c | 849 ++++
- drivers/gpu/drm/amd/dal/dc/core/dc_hw_sequencer.c | 49 +
- drivers/gpu/drm/amd/dal/dc/core/dc_link.c | 1081 +++++
- drivers/gpu/drm/amd/dal/dc/core/dc_link_dp.c | 1689 +++++++
- drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c | 188 +
- drivers/gpu/drm/amd/dal/dc/core/dc_resource.c | 378 ++
- drivers/gpu/drm/amd/dal/dc/core/dc_sink.c | 118 +
- drivers/gpu/drm/amd/dal/dc/core/dc_stream.c | 172 +
- drivers/gpu/drm/amd/dal/dc/core/dc_surface.c | 124 +
- drivers/gpu/drm/amd/dal/dc/core/dc_target.c | 473 ++
- drivers/gpu/drm/amd/dal/dc/dc.h | 440 ++
- drivers/gpu/drm/amd/dal/dc/dc_helpers.h | 75 +
- drivers/gpu/drm/amd/dal/dc/dc_services.h | 174 +
- drivers/gpu/drm/amd/dal/dc/dc_temp.h | 508 +++
- drivers/gpu/drm/amd/dal/dc/dc_types.h | 677 +++
- drivers/gpu/drm/amd/dal/dc/dce110/Makefile | 33 +
- .../gpu/drm/amd/dal/dc/dce110/dce110_compressor.c | 886 ++++
- .../gpu/drm/amd/dal/dc/dce110/dce110_compressor.h | 84 +
- .../drm/amd/dal/dc/dce110/dce110_hw_sequencer.c | 1825 ++++++++
- .../drm/amd/dal/dc/dce110/dce110_hw_sequencer.h | 36 +
- drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp.c | 85 +
- drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp.h | 90 +
- .../gpu/drm/amd/dal/dc/dce110/dce110_ipp_cursor.c | 256 ++
- .../gpu/drm/amd/dal/dc/dce110/dce110_ipp_gamma.c | 877 ++++
- .../drm/amd/dal/dc/dce110/dce110_link_encoder.c | 2049 +++++++++
- .../drm/amd/dal/dc/dce110/dce110_link_encoder.h | 91 +
- .../gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c | 969 ++++
- .../gpu/drm/amd/dal/dc/dce110/dce110_mem_input.h | 88 +
- drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.c | 296 ++
- drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.h | 140 +
- drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_csc.c | 904 ++++
- .../drm/amd/dal/dc/dce110/dce110_opp_formatter.c | 610 +++
- .../gpu/drm/amd/dal/dc/dce110/dce110_opp_regamma.c | 2473 ++++++++++
- .../gpu/drm/amd/dal/dc/dce110/dce110_resource.c | 1276 ++++++
- .../gpu/drm/amd/dal/dc/dce110/dce110_resource.h | 55 +
- .../drm/amd/dal/dc/dce110/dce110_stream_encoder.c | 1168 +++++
- .../drm/amd/dal/dc/dce110/dce110_stream_encoder.h | 64 +
- .../amd/dal/dc/dce110/dce110_timing_generator.c | 1878 ++++++++
- .../amd/dal/dc/dce110/dce110_timing_generator.h | 178 +
- .../gpu/drm/amd/dal/dc/dce110/dce110_transform.c | 116 +
- .../gpu/drm/amd/dal/dc/dce110/dce110_transform.h | 91 +
- .../amd/dal/dc/dce110/dce110_transform_bit_depth.c | 840 ++++
- .../amd/dal/dc/dce110/dce110_transform_bit_depth.h | 51 +
- .../drm/amd/dal/dc/dce110/dce110_transform_gamut.c | 297 ++
- .../drm/amd/dal/dc/dce110/dce110_transform_scl.c | 818 ++++
- .../drm/amd/dal/dc/dce110/dce110_transform_sclv.c | 531 +++
- drivers/gpu/drm/amd/dal/dc/dcs/Makefile | 10 +
- drivers/gpu/drm/amd/dal/dc/dcs/ddc_i2caux_helper.c | 159 +
- drivers/gpu/drm/amd/dal/dc/dcs/ddc_i2caux_helper.h | 60 +
- drivers/gpu/drm/amd/dal/dc/dcs/ddc_service.c | 1034 +++++
- drivers/gpu/drm/amd/dal/dc/dcs/ddc_service.h | 38 +
- drivers/gpu/drm/amd/dal/dc/gpio/Makefile | 24 +
- .../gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.c | 883 ++++
- .../gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.h | 46 +
- .../drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.c | 84 +
- .../drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.h | 32 +
- .../gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.c | 367 ++
- .../gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.h | 47 +
- .../amd/dal/dc/gpio/dce110/hw_translate_dce110.c | 440 ++
- .../amd/dal/dc/gpio/dce110/hw_translate_dce110.h | 34 +
- drivers/gpu/drm/amd/dal/dc/gpio/ddc.c | 290 ++
- drivers/gpu/drm/amd/dal/dc/gpio/ddc.h | 45 +
- drivers/gpu/drm/amd/dal/dc/gpio/dvo.c | 138 +
- drivers/gpu/drm/amd/dal/dc/gpio/dvo.h | 42 +
- drivers/gpu/drm/amd/dal/dc/gpio/gpio.h | 48 +
- drivers/gpu/drm/amd/dal/dc/gpio/gpio_base.c | 279 ++
- drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.c | 470 ++
- drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.h | 57 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c | 105 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.h | 60 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_dvo.c | 318 ++
- drivers/gpu/drm/amd/dal/dc/gpio/hw_dvo.h | 89 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c | 80 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.h | 74 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.c | 408 ++
- drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.h | 129 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.c | 93 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.h | 47 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.c | 86 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.h | 79 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.c | 88 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.h | 45 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c | 67 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.h | 49 +
- drivers/gpu/drm/amd/dal/dc/gpio/irq.c | 181 +
- drivers/gpu/drm/amd/dal/dc/gpio/irq.h | 42 +
- drivers/gpu/drm/amd/dal/dc/gpu/Makefile | 26 +
- .../gpu/drm/amd/dal/dc/gpu/calc_pll_clock_source.c | 407 ++
- .../gpu/drm/amd/dal/dc/gpu/calc_pll_clock_source.h | 79 +
- drivers/gpu/drm/amd/dal/dc/gpu/clock_source.c | 649 +++
- drivers/gpu/drm/amd/dal/dc/gpu/clock_source.h | 136 +
- .../gpu/drm/amd/dal/dc/gpu/dc_clock_generator.c | 92 +
- .../gpu/drm/amd/dal/dc/gpu/dc_clock_generator.h | 63 +
- .../amd/dal/dc/gpu/dce110/dc_clock_gating_dce110.c | 90 +
- .../amd/dal/dc/gpu/dce110/dc_clock_gating_dce110.h | 33 +
- .../amd/dal/dc/gpu/dce110/display_clock_dce110.c | 958 ++++
- .../amd/dal/dc/gpu/dce110/display_clock_dce110.h | 53 +
- .../dal/dc/gpu/dce110/ext_clock_source_dce110.c | 383 ++
- .../dal/dc/gpu/dce110/ext_clock_source_dce110.h | 38 +
- .../dal/dc/gpu/dce110/pll_clock_source_dce110.c | 718 +++
- .../dal/dc/gpu/dce110/pll_clock_source_dce110.h | 55 +
- .../dal/dc/gpu/dce110/vce_clock_source_dce110.c | 193 +
- .../dal/dc/gpu/dce110/vce_clock_source_dce110.h | 32 +
- drivers/gpu/drm/amd/dal/dc/gpu/display_clock.c | 204 +
- drivers/gpu/drm/amd/dal/dc/gpu/display_clock.h | 82 +
- drivers/gpu/drm/amd/dal/dc/gpu/divider_range.c | 127 +
- drivers/gpu/drm/amd/dal/dc/gpu/divider_range.h | 63 +
- drivers/gpu/drm/amd/dal/dc/gpu/ext_clock_source.c | 119 +
- drivers/gpu/drm/amd/dal/dc/gpu/ext_clock_source.h | 47 +
- drivers/gpu/drm/amd/dal/dc/gpu/pll_clock_source.c | 141 +
- drivers/gpu/drm/amd/dal/dc/gpu/pll_clock_source.h | 52 +
- drivers/gpu/drm/amd/dal/dc/i2caux/Makefile | 23 +
- drivers/gpu/drm/amd/dal/dc/i2caux/aux_engine.c | 568 +++
- drivers/gpu/drm/amd/dal/dc/i2caux/aux_engine.h | 119 +
- .../amd/dal/dc/i2caux/dce110/aux_engine_dce110.c | 789 ++++
- .../amd/dal/dc/i2caux/dce110/aux_engine_dce110.h | 56 +
- .../i2caux/dce110/i2c_generic_hw_engine_dce110.h | 25 +
- .../dal/dc/i2caux/dce110/i2c_hw_engine_dce110.c | 954 ++++
- .../dal/dc/i2caux/dce110/i2c_hw_engine_dce110.h | 58 +
- .../dal/dc/i2caux/dce110/i2c_sw_engine_dce110.c | 172 +
- .../dal/dc/i2caux/dce110/i2c_sw_engine_dce110.h | 43 +
- .../drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.c | 260 ++
- .../drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.h | 39 +
- drivers/gpu/drm/amd/dal/dc/i2caux/engine.h | 129 +
- drivers/gpu/drm/amd/dal/dc/i2caux/engine_base.c | 68 +
- drivers/gpu/drm/amd/dal/dc/i2caux/i2c_engine.c | 122 +
- drivers/gpu/drm/amd/dal/dc/i2caux/i2c_engine.h | 113 +
- .../drm/amd/dal/dc/i2caux/i2c_generic_hw_engine.c | 287 ++
- .../drm/amd/dal/dc/i2caux/i2c_generic_hw_engine.h | 77 +
- drivers/gpu/drm/amd/dal/dc/i2caux/i2c_hw_engine.c | 247 +
- drivers/gpu/drm/amd/dal/dc/i2caux/i2c_hw_engine.h | 80 +
- drivers/gpu/drm/amd/dal/dc/i2caux/i2c_sw_engine.c | 615 +++
- drivers/gpu/drm/amd/dal/dc/i2caux/i2c_sw_engine.h | 81 +
- drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c | 519 +++
- drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.h | 123 +
- drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h | 463 ++
- drivers/gpu/drm/amd/dal/dc/inc/bw_fixed.h | 60 +
- drivers/gpu/drm/amd/dal/dc/inc/compressor.h | 140 +
- drivers/gpu/drm/amd/dal/dc/inc/core_dc.h | 39 +
- drivers/gpu/drm/amd/dal/dc/inc/core_status.h | 46 +
- drivers/gpu/drm/amd/dal/dc/inc/core_types.h | 308 ++
- drivers/gpu/drm/amd/dal/dc/inc/dc_link_dp.h | 51 +
- drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h | 170 +
- drivers/gpu/drm/amd/dal/dc/inc/ipp.h | 66 +
- drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h | 67 +
- drivers/gpu/drm/amd/dal/dc/inc/mem_input.h | 55 +
- drivers/gpu/drm/amd/dal/dc/inc/opp.h | 206 +
- drivers/gpu/drm/amd/dal/dc/inc/resource.h | 61 +
- drivers/gpu/drm/amd/dal/dc/inc/transform.h | 81 +
- drivers/gpu/drm/amd/dal/dc/irq/Makefile | 21 +
- .../drm/amd/dal/dc/irq/dce110/irq_service_dce110.c | 389 ++
- .../drm/amd/dal/dc/irq/dce110/irq_service_dce110.h | 34 +
- drivers/gpu/drm/amd/dal/dc/irq/irq_service.c | 173 +
- drivers/gpu/drm/amd/dal/dc/irq/irq_service.h | 85 +
- drivers/gpu/drm/amd/dal/dc/irq_types.h | 199 +
- .../amd/dal/include/adapter_service_interface.h | 628 +++
- .../drm/amd/dal/include/adapter_service_types.h | 70 +
- .../gpu/drm/amd/dal/include/adjustment_interface.h | 230 +
- drivers/gpu/drm/amd/dal/include/adjustment_types.h | 420 ++
- .../amd/dal/include/asic_capability_interface.h | 58 +
- .../drm/amd/dal/include/asic_capability_types.h | 134 +
- drivers/gpu/drm/amd/dal/include/audio_interface.h | 184 +
- drivers/gpu/drm/amd/dal/include/audio_types.h | 275 ++
- .../drm/amd/dal/include/bios_parser_interface.h | 294 ++
- .../gpu/drm/amd/dal/include/bios_parser_types.h | 305 ++
- drivers/gpu/drm/amd/dal/include/bit_set.h | 61 +
- .../drm/amd/dal/include/clock_source_interface.h | 89 +
- .../gpu/drm/amd/dal/include/clock_source_types.h | 118 +
- .../gpu/drm/amd/dal/include/connector_interface.h | 82 +
- drivers/gpu/drm/amd/dal/include/dal_asic_id.h | 106 +
- .../gpu/drm/amd/dal/include/dal_register_logger.h | 43 +
- drivers/gpu/drm/amd/dal/include/dal_types.h | 292 ++
- .../amd/dal/include/dc_clock_generator_interface.h | 77 +
- drivers/gpu/drm/amd/dal/include/dcs_interface.h | 351 ++
- drivers/gpu/drm/amd/dal/include/dcs_types.h | 742 +++
- drivers/gpu/drm/amd/dal/include/ddc_interface.h | 74 +
- .../drm/amd/dal/include/ddc_service_interface.h | 100 +
- .../gpu/drm/amd/dal/include/ddc_service_types.h | 220 +
- .../amd/dal/include/default_mode_list_interface.h | 37 +
- .../drm/amd/dal/include/display_clock_interface.h | 189 +
- .../drm/amd/dal/include/display_path_interface.h | 436 ++
- .../gpu/drm/amd/dal/include/display_path_types.h | 132 +
- .../amd/dal/include/display_service_interface.h | 165 +
- .../drm/amd/dal/include/display_service_types.h | 167 +
- drivers/gpu/drm/amd/dal/include/dmcu_interface.h | 87 +
- drivers/gpu/drm/amd/dal/include/dmcu_types.h | 199 +
- .../dal/include/dpcd_access_service_interface.h | 65 +
- drivers/gpu/drm/amd/dal/include/dpcd_defs.h | 869 ++++
- drivers/gpu/drm/amd/dal/include/dvo_interface.h | 48 +
- .../gpu/drm/amd/dal/include/encoder_interface.h | 278 ++
- drivers/gpu/drm/amd/dal/include/encoder_types.h | 216 +
- drivers/gpu/drm/amd/dal/include/fixed31_32.h | 389 ++
- drivers/gpu/drm/amd/dal/include/fixed32_32.h | 80 +
- drivers/gpu/drm/amd/dal/include/gpio_interface.h | 93 +
- .../drm/amd/dal/include/gpio_service_interface.h | 94 +
- drivers/gpu/drm/amd/dal/include/gpio_types.h | 393 ++
- drivers/gpu/drm/amd/dal/include/gpu_clock_info.h | 43 +
- drivers/gpu/drm/amd/dal/include/gpu_interface.h | 91 +
- drivers/gpu/drm/amd/dal/include/grph_csc_types.h | 98 +
- .../drm/amd/dal/include/grph_object_ctrl_defs.h | 598 +++
- drivers/gpu/drm/amd/dal/include/grph_object_defs.h | 328 ++
- drivers/gpu/drm/amd/dal/include/grph_object_id.h | 285 ++
- .../gpu/drm/amd/dal/include/hw_adjustment_set.h | 50 +
- .../gpu/drm/amd/dal/include/hw_adjustment_types.h | 205 +
- .../amd/dal/include/hw_path_mode_set_interface.h | 48 +
- .../drm/amd/dal/include/hw_sequencer_interface.h | 388 ++
- .../gpu/drm/amd/dal/include/hw_sequencer_types.h | 305 ++
- drivers/gpu/drm/amd/dal/include/i2caux_interface.h | 127 +
- drivers/gpu/drm/amd/dal/include/irq_interface.h | 53 +
- .../drm/amd/dal/include/irq_service_interface.h | 55 +
- drivers/gpu/drm/amd/dal/include/isr_config_types.h | 157 +
- .../gpu/drm/amd/dal/include/link_encoder_types.h | 32 +
- .../drm/amd/dal/include/link_service_interface.h | 202 +
- .../gpu/drm/amd/dal/include/link_service_types.h | 428 ++
- drivers/gpu/drm/amd/dal/include/logger_interface.h | 153 +
- drivers/gpu/drm/amd/dal/include/logger_types.h | 356 ++
- .../gpu/drm/amd/dal/include/mode_manager_types.h | 71 +
- .../gpu/drm/amd/dal/include/mode_query_interface.h | 93 +
- .../amd/dal/include/mode_timing_list_interface.h | 51 +
- .../gpu/drm/amd/dal/include/overlay_interface.h | 137 +
- drivers/gpu/drm/amd/dal/include/overlay_types.h | 164 +
- .../drm/amd/dal/include/path_mode_set_interface.h | 107 +
- drivers/gpu/drm/amd/dal/include/plane_types.h | 309 ++
- drivers/gpu/drm/amd/dal/include/scaler_types.h | 196 +
- .../amd/dal/include/set_mode_params_interface.h | 101 +
- drivers/gpu/drm/amd/dal/include/set_mode_types.h | 285 ++
- drivers/gpu/drm/amd/dal/include/signal_types.h | 58 +
- .../gpu/drm/amd/dal/include/stream_encoder_types.h | 16 +
- .../drm/amd/dal/include/timing_generator_types.h | 150 +
- .../amd/dal/include/timing_list_query_interface.h | 69 +
- drivers/gpu/drm/amd/dal/include/vector.h | 150 +
- drivers/gpu/drm/amd/dal/include/video_csc_types.h | 135 +
- .../gpu/drm/amd/dal/include/video_gamma_types.h | 56 +
- 294 files changed, 87748 insertions(+)
- create mode 100644 drivers/gpu/drm/amd/dal/Kconfig
- create mode 100644 drivers/gpu/drm/amd/dal/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dal_power_interface_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/dal_services.h
- create mode 100644 drivers/gpu/drm/amd/dal/dal_services_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/asic_capability/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/asic_capability/asic_capability.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/asic_capability/carrizo_asic_capability.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/asic_capability/carrizo_asic_capability.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/audio.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/audio_base.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/dce110/audio_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/dce110/audio_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/dce110/hw_ctx_audio_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/dce110/hw_ctx_audio_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/hw_ctx_audio.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/hw_ctx_audio.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/conversion.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/conversion.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/fixpt31_32.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/fixpt32_32.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/grph_object_id.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/logger.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/logger.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/register_logger.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/signal_types.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/vector.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/bios_parser.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/bios_parser.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/command_table.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/command_table.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/command_table_helper.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/command_table_helper.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/dce110/bios_parser_helper_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/dce110/bios_parser_helper_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/dce110/command_table_helper_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/dce110/command_table_helper_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/calcs/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/calcs/bw_fixed.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/calcs/scaler_filter.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/calcs/scaler_filter.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/connector/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/connector/connector.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/connector/connector_base.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/connector/connector_signals.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/core/dc.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/core/dc_hw_sequencer.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/core/dc_link.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/core/dc_link_dp.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/core/dc_resource.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/core/dc_sink.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/core/dc_stream.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/core/dc_surface.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/core/dc_target.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dc.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dc_helpers.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dc_services.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dc_temp.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dc_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_compressor.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_compressor.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp_cursor.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp_gamma.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_csc.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_formatter.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_regamma.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_bit_depth.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_bit_depth.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_gamut.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_scl.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_sclv.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dcs/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dcs/ddc_i2caux_helper.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dcs/ddc_i2caux_helper.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dcs/ddc_service.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dcs/ddc_service.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/ddc.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/ddc.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dvo.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dvo.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/gpio.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/gpio_base.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_dvo.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_dvo.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/irq.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/irq.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/calc_pll_clock_source.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/calc_pll_clock_source.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/clock_source.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/clock_source.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dc_clock_generator.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dc_clock_generator.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce110/dc_clock_gating_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce110/dc_clock_gating_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce110/display_clock_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce110/display_clock_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce110/ext_clock_source_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce110/ext_clock_source_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce110/pll_clock_source_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce110/pll_clock_source_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce110/vce_clock_source_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce110/vce_clock_source_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/display_clock.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/display_clock.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/divider_range.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/divider_range.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/ext_clock_source.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/ext_clock_source.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/pll_clock_source.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/pll_clock_source.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/aux_engine.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/aux_engine.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce110/aux_engine_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce110/aux_engine_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_generic_hw_engine_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_sw_engine_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_sw_engine_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/engine.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/engine_base.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/i2c_engine.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/i2c_engine.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/i2c_generic_hw_engine.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/i2c_generic_hw_engine.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/i2c_hw_engine.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/i2c_hw_engine.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/i2c_sw_engine.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/i2c_sw_engine.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/bw_fixed.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/compressor.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/core_dc.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/core_status.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/core_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/dc_link_dp.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/ipp.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/mem_input.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/opp.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/resource.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/inc/transform.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/irq/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/irq/irq_service.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/irq/irq_service.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/irq_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/adapter_service_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/adapter_service_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/adjustment_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/adjustment_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/asic_capability_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/asic_capability_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/audio_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/audio_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/bios_parser_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/bios_parser_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/bit_set.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/clock_source_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/clock_source_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/connector_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/dal_asic_id.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/dal_register_logger.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/dal_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/dc_clock_generator_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/dcs_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/dcs_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/ddc_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/ddc_service_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/ddc_service_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/default_mode_list_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/display_clock_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/display_path_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/display_path_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/display_service_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/display_service_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/dmcu_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/dmcu_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/dpcd_access_service_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/dpcd_defs.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/dvo_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/encoder_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/encoder_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/fixed31_32.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/fixed32_32.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/gpio_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/gpio_service_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/gpio_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/gpu_clock_info.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/gpu_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/grph_csc_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/grph_object_ctrl_defs.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/grph_object_defs.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/grph_object_id.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/hw_adjustment_set.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/hw_adjustment_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/hw_path_mode_set_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/hw_sequencer_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/hw_sequencer_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/i2caux_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/irq_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/irq_service_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/isr_config_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/link_encoder_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/link_service_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/link_service_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/logger_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/logger_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/mode_manager_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/mode_query_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/mode_timing_list_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/overlay_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/overlay_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/path_mode_set_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/plane_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/scaler_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/set_mode_params_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/set_mode_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/signal_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/stream_encoder_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/timing_generator_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/timing_list_query_interface.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/vector.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/video_csc_types.h
- create mode 100644 drivers/gpu/drm/amd/dal/include/video_gamma_types.h
-
-diff --git a/drivers/gpu/drm/amd/dal/Kconfig b/drivers/gpu/drm/amd/dal/Kconfig
-new file mode 100644
-index 0000000..14df02e
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/Kconfig
-@@ -0,0 +1,39 @@
-+menu "Display Engine Configuration"
-+ depends on DRM && (DRM_AMDSOC || DRM_AMDGPU)
-+
-+config DRM_AMD_DAL
-+ bool "AMD DAL - Enable new display engine (will be deprecated when the development is done)"
-+ help
-+ Choose this option if you want to use the new display engine
-+ support for AMD SOC.
-+
-+ Will be deprecated when the DAL component becomes stable and
-+ AMDSOC will fully switch to it.
-+
-+config DRM_AMD_DAL_VBIOS_PRESENT
-+ bool "Video Bios available on board"
-+ depends on DRM_AMD_DAL
-+ help
-+ This option is needed to allow a full range of feature
-+ support when working on
-+ x86 platforms and there is a VBIOS
-+ present in the system
-+
-+config DRM_AMD_DAL_DCE11_0
-+ bool "Carrizo family"
-+ depends on DRM_AMD_DAL
-+ help
-+ Choose this option
-+ if you want to have
-+ CZ family
-+ for display engine
-+
-+config DEBUG_KERNEL_DAL
-+ bool "Enable kgdb break in DAL"
-+ depends on DRM_AMD_DAL
-+ help
-+ Choose this option
-+ if you want to hit
-+ kdgb_break in assert.
-+
-+endmenu
-diff --git a/drivers/gpu/drm/amd/dal/Makefile b/drivers/gpu/drm/amd/dal/Makefile
-new file mode 100644
-index 0000000..bdf5d18
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/Makefile
-@@ -0,0 +1,19 @@
-+#
-+# Makefile for the DAL (Display Abstract Layer), which is a sub-component
-+# of the AMDGPU drm driver.
-+# It provides the HW control for display related functionalities.
-+
-+AMDDALPATH = $(RELATIVE_AMD_DAL_PATH)
-+
-+subdir-ccflags-y += -I$(AMDDALPATH)/ -I$(AMDDALPATH)/include -DDAL_CZ_BRINGUP
-+
-+subdir-ccflags-y += -I$(FULL_AMD_DAL_PATH)/dc/inc/
-+
-+#TODO: remove when Timing Sync feature is complete
-+subdir-ccflags-y += -DBUILD_FEATURE_TIMING_SYNC=0
-+
-+DAL_LIBS = amdgpu_dm dc
-+
-+AMD_DAL = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DAL_PATH)/,$(DAL_LIBS)))
-+
-+include $(AMD_DAL)
-diff --git a/drivers/gpu/drm/amd/dal/dal_power_interface_types.h b/drivers/gpu/drm/amd/dal/dal_power_interface_types.h
-new file mode 100644
-index 0000000..82e8ca2
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dal_power_interface_types.h
-@@ -0,0 +1,76 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_POWER_INTERFACE_TYPES_H__
-+#define __DAL_POWER_INTERFACE_TYPES_H__
-+
-+enum dal_to_power_clocks_state {
-+ PP_CLOCKS_STATE_INVALID,
-+ PP_CLOCKS_STATE_ULTRA_LOW,
-+ PP_CLOCKS_STATE_LOW,
-+ PP_CLOCKS_STATE_NOMINAL,
-+ PP_CLOCKS_STATE_PERFORMANCE
-+};
-+
-+/* clocks in khz */
-+struct dal_to_power_info {
-+ enum dal_to_power_clocks_state required_clock;
-+ uint32_t min_sclk;
-+ uint32_t min_mclk;
-+ uint32_t min_deep_sleep_sclk;
-+};
-+
-+/* clocks in khz */
-+struct power_to_dal_info {
-+ uint32_t min_sclk;
-+ uint32_t max_sclk;
-+ uint32_t min_mclk;
-+ uint32_t max_mclk;
-+};
-+
-+/* clocks in khz */
-+struct dal_system_clock_range {
-+ uint32_t min_sclk;
-+ uint32_t max_sclk;
-+
-+ uint32_t min_mclk;
-+ uint32_t max_mclk;
-+
-+ uint32_t min_dclk;
-+ uint32_t max_dclk;
-+
-+ /* Wireless Display */
-+ uint32_t min_eclk;
-+ uint32_t max_eclk;
-+};
-+
-+/* clocks in khz */
-+struct dal_to_power_dclk {
-+ uint32_t optimal; /* input: best optimizes for stutter efficiency */
-+ uint32_t minimal; /* input: the lowest clk that DAL can support */
-+ uint32_t established; /* output: the actually set one */
-+};
-+
-+#endif /* __DAL_POWER_INTERFACE_TYPES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dal_services.h b/drivers/gpu/drm/amd/dal/dal_services.h
-new file mode 100644
-index 0000000..398e4e5
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dal_services.h
-@@ -0,0 +1,266 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_SERVICES_H__
-+#define __DAL_SERVICES_H__
-+
-+/* DC headers*/
-+#include "dc/dc_services.h"
-+
-+#include "dal_power_interface_types.h"
-+
-+#include "irq_types.h"
-+#include "include/dal_types.h"
-+
-+/* TODO: investigate if it can be removed. */
-+/* Undefine DEPRECATED because it conflicts with printk.h */
-+#undef DEPRECATED
-+
-+/*
-+ *
-+ * interrupt services to register and unregister handlers
-+ *
-+ */
-+
-+/* the timer "interrupt" current implementation supports only
-+'one-shot' type, and LOW level (asynchronous) context */
-+void dal_register_timer_interrupt(
-+ struct dc_context *ctx,
-+ struct dc_timer_interrupt_params *int_params,
-+ interrupt_handler ih,
-+ void *handler_args);
-+
-+/*
-+ *
-+ * kernel memory manipulation
-+ *
-+ */
-+
-+/* Reallocate memory. The contents will remain unchanged.*/
-+void *dc_service_realloc(struct dc_context *ctx, const void *ptr, uint32_t size);
-+
-+void dc_service_memmove(void *dst, const void *src, uint32_t size);
-+
-+void dc_service_memset(void *p, int32_t c, uint32_t count);
-+
-+int32_t dal_memcmp(const void *p1, const void *p2, uint32_t count);
-+
-+int32_t dal_strncmp(const int8_t *p1, const int8_t *p2, uint32_t count);
-+
-+/*
-+ *
-+ * GPU registers access
-+ *
-+ */
-+static inline uint32_t dal_read_reg(
-+ const struct dc_context *ctx,
-+ uint32_t address)
-+{
-+ uint32_t value = cgs_read_register(ctx->cgs_device, address);
-+
-+#if defined(__DAL_REGISTER_LOGGER__)
-+ if (true == dal_reg_logger_should_dump_register()) {
-+ dal_reg_logger_rw_count_increment();
-+ DRM_INFO("%s 0x%x 0x%x\n", __func__, address, value);
-+ }
-+#endif
-+ return value;
-+}
-+
-+static inline uint32_t get_reg_field_value_ex(
-+ uint32_t reg_value,
-+ uint32_t mask,
-+ uint8_t shift)
-+{
-+ return (mask & reg_value) >> shift;
-+}
-+
-+#define get_reg_field_value(reg_value, reg_name, reg_field)\
-+ get_reg_field_value_ex(\
-+ (reg_value),\
-+ reg_name ## __ ## reg_field ## _MASK,\
-+ reg_name ## __ ## reg_field ## __SHIFT)
-+
-+static inline uint32_t set_reg_field_value_ex(
-+ uint32_t reg_value,
-+ uint32_t value,
-+ uint32_t mask,
-+ uint8_t shift)
-+{
-+ return (reg_value & ~mask) | (mask & (value << shift));
-+}
-+
-+#define set_reg_field_value(reg_value, value, reg_name, reg_field)\
-+ (reg_value) = set_reg_field_value_ex(\
-+ (reg_value),\
-+ (value),\
-+ reg_name ## __ ## reg_field ## _MASK,\
-+ reg_name ## __ ## reg_field ## __SHIFT)
-+
-+static inline void dal_write_reg(
-+ const struct dc_context *ctx,
-+ uint32_t address,
-+ uint32_t value)
-+{
-+#if defined(__DAL_REGISTER_LOGGER__)
-+ if (true == dal_reg_logger_should_dump_register()) {
-+ dal_reg_logger_rw_count_increment();
-+ DRM_INFO("%s 0x%x 0x%x\n", __func__, address, value);
-+ }
-+#endif
-+ cgs_write_register(ctx->cgs_device, address, value);
-+}
-+
-+static inline uint32_t dal_read_index_reg(
-+ const struct dc_context *ctx,
-+ enum cgs_ind_reg addr_space,
-+ uint32_t index)
-+{
-+ return cgs_read_ind_register(ctx->cgs_device,addr_space,index);
-+}
-+
-+static inline void dal_write_index_reg(
-+ const struct dc_context *ctx,
-+ enum cgs_ind_reg addr_space,
-+ uint32_t index,
-+ uint32_t value)
-+{
-+ cgs_write_ind_register(ctx->cgs_device,addr_space,index,value);
-+}
-+
-+enum platform_method {
-+ PM_GET_AVAILABLE_METHODS = 1 << 0,
-+ PM_GET_LID_STATE = 1 << 1,
-+ PM_GET_EXTENDED_BRIGHNESS_CAPS = 1 << 2
-+};
-+
-+struct platform_info_params {
-+ enum platform_method method;
-+ void *data;
-+};
-+
-+struct platform_info_brightness_caps {
-+ uint8_t ac_level_percentage;
-+ uint8_t dc_level_percentage;
-+};
-+
-+struct platform_info_ext_brightness_caps {
-+ struct platform_info_brightness_caps basic_caps;
-+ struct data_point {
-+ uint8_t luminance;
-+ uint8_t signal_level;
-+ } data_points[99];
-+
-+ uint8_t data_points_num;
-+ uint8_t min_input_signal;
-+ uint8_t max_input_signal;
-+};
-+
-+bool dal_get_platform_info(
-+ struct dc_context *ctx,
-+ struct platform_info_params *params);
-+
-+
-+static inline uint32_t dal_bios_cmd_table_para_revision(
-+ struct dc_context *ctx,
-+ uint32_t index)
-+{
-+ uint8_t frev;
-+ uint8_t crev;
-+
-+ if (cgs_atom_get_cmd_table_revs(
-+ ctx->cgs_device,
-+ index,
-+ &frev,
-+ &crev) != 0)
-+ return 0;
-+
-+ return crev;
-+}
-+
-+/* Calls to notification */
-+
-+/* Notify display manager for hotplug event */
-+void dal_notify_hotplug(
-+ struct dc_context *ctx,
-+ uint32_t display_index,
-+ bool is_connected);
-+
-+
-+void dal_notify_setmode_complete(
-+ struct dc_context *ctx,
-+ uint32_t h_total,
-+ uint32_t v_total,
-+ uint32_t h_active,
-+ uint32_t v_active,
-+ uint32_t pix_clk_in_khz);
-+
-+/* End of notification calls */
-+
-+/*
-+ *
-+ * Delay functions.
-+ *
-+ *
-+ */
-+
-+/* Following the guidance:
-+ * https://www.kernel.org/doc/Documentation/timers/timers-howto.txt
-+ *
-+ * This is a busy wait for nano seconds and should be used only for
-+ * extremely short ranges
-+ */
-+void dal_delay_in_nanoseconds(uint32_t nanoseconds);
-+
-+
-+/*
-+ *
-+ * atombios services
-+ *
-+ */
-+
-+bool dal_exec_bios_cmd_table(
-+ struct dc_context *ctx,
-+ uint32_t index,
-+ void *params);
-+
-+/*
-+ *
-+ * print-out services
-+ *
-+ */
-+#define dal_log_to_buffer(buffer, size, fmt, args)\
-+ vsnprintf(buffer, size, fmt, args)
-+
-+long dal_get_pid(void);
-+long dal_get_tgid(void);
-+
-+/*
-+ *
-+ * general debug capabilities
-+ *
-+ */
-+
-+#endif /* __DAL_SERVICES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dal_services_types.h b/drivers/gpu/drm/amd/dal/dal_services_types.h
-new file mode 100644
-index 0000000..89c73c6
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dal_services_types.h
-@@ -0,0 +1,62 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_SERVICES_TYPES_H__
-+#define __DAL_SERVICES_TYPES_H__
-+
-+#define INVALID_DISPLAY_INDEX 0xffffffff
-+
-+#if defined __KERNEL__
-+
-+#include <asm/byteorder.h>
-+#include <linux/types.h>
-+#include <drm/drmP.h>
-+
-+#include "cgs_linux.h"
-+
-+#if defined(__BIG_ENDIAN) && !defined(BIGENDIAN_CPU)
-+#define BIGENDIAN_CPU
-+#elif defined(__LITTLE_ENDIAN) && !defined(LITTLEENDIAN_CPU)
-+#define LITTLEENDIAN_CPU
-+#endif
-+
-+#undef READ
-+#undef WRITE
-+#undef FRAME_SIZE
-+
-+#define dal_output_to_console(fmt, ...) DRM_INFO(fmt, ##__VA_ARGS__)
-+
-+#define dal_error(fmt, ...) DRM_ERROR(fmt, ##__VA_ARGS__)
-+
-+#define dal_debug(fmt, ...) DRM_DEBUG_KMS(fmt, ##__VA_ARGS__)
-+
-+#define dal_vlog(fmt, args) vprintk(fmt, args)
-+
-+#define dal_min(x, y) min(x, y)
-+#define dal_max(x, y) max(x, y)
-+
-+#endif
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/Makefile b/drivers/gpu/drm/amd/dal/dc/Makefile
-new file mode 100644
-index 0000000..6926356
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/Makefile
-@@ -0,0 +1,24 @@
-+#
-+# Makefile for Display Core (dc) component.
-+#
-+
-+DC_LIBS = adapter asic_capability audio basics bios calcs connector \
-+dcs gpio gpu i2caux irq
-+
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_0
-+DC_LIBS += dce110
-+endif
-+
-+AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DAL_PATH)/dc/,$(DC_LIBS)))
-+
-+include $(AMD_DC)
-+
-+DISPLAY_CORE = dc.o dc_link.o dc_resource.o dc_target.o dc_sink.o dc_stream.o \
-+dc_hw_sequencer.o dc_surface.o dc_link_hwss.o dc_link_dp.o
-+
-+AMD_DISPLAY_CORE = $(addprefix $(AMDDALPATH)/dc/core/,$(DISPLAY_CORE))
-+
-+AMD_DAL_FILES += $(AMD_DISPLAY_CORE)
-+
-+
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/Makefile b/drivers/gpu/drm/amd/dal/dc/adapter/Makefile
-new file mode 100644
-index 0000000..8ede504
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/Makefile
-@@ -0,0 +1,18 @@
-+#
-+# Makefile for the 'adapter' sub-component of DAL.
-+# It provides the control and status of HW adapter.
-+
-+ADAPTER = adapter_service.o hw_ctx_adapter_service.o wireless_data_source.o
-+
-+AMD_DAL_ADAPTER = $(addprefix $(AMDDALPATH)/dc/adapter/,$(ADAPTER))
-+
-+AMD_DAL_FILES += $(AMD_DAL_ADAPTER)
-+
-+
-+###############################################################################
-+# DCE 11x
-+###############################################################################
-+
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_0
-+AMD_DAL_FILES += $(AMDDALPATH)/dc/adapter/dce110/hw_ctx_adapter_service_dce110.o
-+endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c
-new file mode 100644
-index 0000000..4f9a637
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c
-@@ -0,0 +1,2037 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+
-+#include "dal_services.h"
-+
-+#include "include/adapter_service_interface.h"
-+#include "include/i2caux_interface.h"
-+#include "include/asic_capability_types.h"
-+#include "include/bios_parser_interface.h"
-+#include "include/gpio_service_interface.h"
-+#include "include/asic_capability_interface.h"
-+#include "include/logger_interface.h"
-+
-+#include "adapter_service.h"
-+#include "hw_ctx_adapter_service.h"
-+#include "wireless_data_source.h"
-+
-+#include "atom.h"
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+#include "dce110/hw_ctx_adapter_service_dce110.h"
-+#endif
-+
-+/*
-+ * Adapter service feature entry table.
-+ *
-+ * This is an array of features that is used to generate feature set. Each
-+ * entry consists three element:
-+ *
-+ * Feature name, default value, and if this feature is a boolean type. A
-+ * feature can only be a boolean or int type.
-+ *
-+ * Example 1: a boolean type feature
-+ * FEATURE_ENABLE_HW_EDID_POLLING, false, true
-+ *
-+ * First element is feature name: EATURE_ENABLE_HW_EDID_POLLING, it has a
-+ * default value 0, and it is a boolean feature.
-+ *
-+ * Example 2: an int type feature
-+ * FEATURE_DCP_PROGRAMMING_WA, 0x1FF7, false
-+ *
-+ * In this case, the default value is 0x1FF7 and not a boolean type, which
-+ * makes it an int type.
-+ */
-+
-+static
-+#if !defined(DAL_CZ_BRINGUP)
-+const
-+#endif
-+struct feature_source_entry feature_entry_table[] = {
-+ /* Feature name | default value | is boolean type */
-+ {FEATURE_ENABLE_HW_EDID_POLLING, false, true},
-+ {FEATURE_DP_SINK_DETECT_POLL_DATA_PIN, false, true},
-+ {FEATURE_UNDERFLOW_INTERRUPT, false, true},
-+ {FEATURE_ALLOW_WATERMARK_ADJUSTMENT, false, true},
-+ {FEATURE_LIGHT_SLEEP, false, true},
-+ {FEATURE_DCP_DITHER_FRAME_RANDOM_ENABLE, false, true},
-+ {FEATURE_DCP_DITHER_RGB_RANDOM_ENABLE, false, true},
-+ {FEATURE_DCP_DITHER_HIGH_PASS_RANDOM_ENABLE, false, true},
-+ {FEATURE_LINE_BUFFER_ENHANCED_PIXEL_DEPTH, false, true},
-+ {FEATURE_MAXIMIZE_URGENCY_WATERMARKS, false, true},
-+ {FEATURE_MAXIMIZE_STUTTER_MARKS, false, true},
-+ {FEATURE_MAXIMIZE_NBP_MARKS, false, true},
-+ /*
-+ * We meet HW I2C issue when test S3 resume on KB.
-+ * An EPR is created for debug the issue.
-+ * Make Test has already been implemented
-+ * with HW I2C. The work load for revert back to SW I2C in make test
-+ * is big. Below is workaround for this issue.
-+ * Driver uses SW I2C.
-+ * Make Test uses HW I2C.
-+ */
-+#if defined(DAL_CZ_BRINGUP)
-+ {FEATURE_RESTORE_USAGE_I2C_SW_ENGINE, true, true},
-+#else
-+ {FEATURE_RESTORE_USAGE_I2C_SW_ENGINE, false, true},
-+#endif
-+ {FEATURE_USE_MAX_DISPLAY_CLK, false, true},
-+ {FEATURE_ALLOW_EDP_RESOURCE_SHARING, false, true},
-+ {FEATURE_SUPPORT_DP_YUV, false, true},
-+ {FEATURE_SUPPORT_DP_Y_ONLY, false, true},
-+ {FEATURE_DISABLE_DP_GTC_SYNC, true, true},
-+ {FEATURE_MODIFY_TIMINGS_FOR_WIRELESS, false, true},
-+ {FEATURE_DCP_BIT_DEPTH_REDUCTION_MODE, 0, false},
-+ {FEATURE_DCP_DITHER_MODE, 0, false},
-+ {FEATURE_DCP_PROGRAMMING_WA, 0, false},
-+ {FEATURE_NO_HPD_LOW_POLLING_VCC_OFF, false, true},
-+ {FEATURE_ENABLE_DFS_BYPASS, false, true},
-+ {FEATURE_WIRELESS_FULL_TIMING_ADJUSTMENT, false, true},
-+ {FEATURE_MAX_COFUNC_NON_DP_DISPLAYS, 2, false},
-+ {FEATURE_WIRELESS_LIMIT_720P, false, true},
-+ {FEATURE_MODIFY_TIMINGS_FOR_WIRELESS, false, true},
-+ {FEATURE_SUPPORTED_HDMI_CONNECTION_NUM, 0, false},
-+ {FEATURE_DETECT_REQUIRE_HPD_HIGH, false, true},
-+ {FEATURE_NO_HPD_LOW_POLLING_VCC_OFF, false, true},
-+ {FEATURE_LB_HIGH_RESOLUTION, false, true},
-+ {FEATURE_MAX_CONTROLLER_NUM, 0, false},
-+ {FEATURE_DRR_SUPPORT, AS_DRR_SUPPORT_ENABLED, false},
-+ {FEATURE_STUTTER_MODE, 15, false},
-+ {FEATURE_DP_DISPLAY_FORCE_SS_ENABLE, false, true},
-+ {FEATURE_REPORT_CE_MODE_ONLY, false, true},
-+ {FEATURE_ALLOW_OPTIMIZED_MODE_AS_DEFAULT, false, true},
-+ {FEATURE_DDC_READ_FORCE_REPEATED_START, false, true},
-+ {FEATURE_FORCE_TIMING_RESYNC, false, true},
-+ {FEATURE_TMDS_DISABLE_DITHERING, false, true},
-+ {FEATURE_HDMI_DISABLE_DITHERING, false, true},
-+ {FEATURE_DP_DISABLE_DITHERING, false, true},
-+ {FEATURE_EMBEDDED_DISABLE_DITHERING, true, true},
-+ {FEATURE_ALLOW_SELF_REFRESH, false, true},
-+ {FEATURE_ALLOW_DYNAMIC_PIXEL_ENCODING_CHANGE, false, true},
-+ {FEATURE_ALLOW_HSYNC_VSYNC_ADJUSTMENT, false, true},
-+ {FEATURE_FORCE_PSR, false, true},
-+ {FEATURE_PSR_SETUP_TIME_TEST, 0, false},
-+ {FEATURE_POWER_GATING_PIPE_IN_TILE, true, true},
-+ {FEATURE_POWER_GATING_LB_PORTION, true, true},
-+ {FEATURE_PREFER_3D_TIMING, false, true},
-+ {FEATURE_VARI_BRIGHT_ENABLE, true, true},
-+ {FEATURE_PSR_ENABLE, false, true},
-+ {FEATURE_WIRELESS_ENABLE_COMPRESSED_AUDIO, false, true},
-+ {FEATURE_WIRELESS_INCLUDE_UNVERIFIED_TIMINGS, true, true},
-+ {FEATURE_EDID_STRESS_READ, false, true},
-+ {FEATURE_DP_FRAME_PACK_STEREO3D, false, true},
-+ {FEATURE_DISPLAY_PREFERRED_VIEW, 0, false},
-+ {FEATURE_ALLOW_HDMI_WITHOUT_AUDIO, false, true},
-+ {FEATURE_ABM_2_0, false, true},
-+ {FEATURE_SUPPORT_MIRABILIS, false, true},
-+ {FEATURE_OPTIMIZATION, 0xFFFF, false},
-+ {FEATURE_PERF_MEASURE, 0, false},
-+ {FEATURE_MIN_BACKLIGHT_LEVEL, 0, false},
-+ {FEATURE_MAX_BACKLIGHT_LEVEL, 255, false},
-+ {FEATURE_LOAD_DMCU_FIRMWARE, true, true},
-+ {FEATURE_DISABLE_AZ_CLOCK_GATING, false, true},
-+ {FEATURE_ENABLE_GPU_SCALING, false, true},
-+ {FEATURE_DONGLE_SINK_COUNT_CHECK, true, true},
-+ {FEATURE_INSTANT_UP_SCALE_DOWN_SCALE, false, true},
-+ {FEATURE_TILED_DISPLAY, false, true},
-+ {FEATURE_PREFERRED_ABM_CONFIG_SET, 0, false},
-+ {FEATURE_CHANGE_SW_I2C_SPEED, 50, false},
-+ {FEATURE_CHANGE_HW_I2C_SPEED, 50, false},
-+ {FEATURE_CHANGE_I2C_SPEED_CONTROL, false, true},
-+ {FEATURE_DEFAULT_PSR_LEVEL, 0, false},
-+ {FEATURE_MAX_CLOCK_SOURCE_NUM, 0, false},
-+ {FEATURE_REPORT_SINGLE_SELECTED_TIMING, false, true},
-+ {FEATURE_ALLOW_HDMI_HIGH_CLK_DP_DONGLE, true, true},
-+ {FEATURE_SUPPORT_EXTERNAL_PANEL_DRR, false, true},
-+ {FEATURE_LVDS_SAFE_PIXEL_CLOCK_RANGE, 0, false},
-+ {FEATURE_ABM_CONFIG, 0, false},
-+ {FEATURE_WIRELESS_ENABLE, false, true},
-+ {FEATURE_ALLOW_DIRECT_MEMORY_ACCESS_TRIG, false, true},
-+ {FEATURE_FORCE_STATIC_SCREEN_EVENT_TRIGGERS, 0, false},
-+ {FEATURE_USE_PPLIB, true, true},
-+ {FEATURE_DISABLE_LPT_SUPPORT, false, true},
-+ {FEATURE_DUMMY_FBC_BACKEND, false, true},
-+ {FEATURE_DPMS_AUDIO_ENDPOINT_CONTROL, true, true},
-+ {FEATURE_DISABLE_FBC_COMP_CLK_GATE, false, true},
-+ {FEATURE_PIXEL_PERFECT_OUTPUT, false, true},
-+ {FEATURE_8BPP_SUPPORTED, false, true}
-+};
-+
-+
-+/* Stores entire ASIC features by sets */
-+uint32_t adapter_feature_set[FEATURE_MAXIMUM/32];
-+
-+enum {
-+ LEGACY_MAX_NUM_OF_CONTROLLERS = 2,
-+ DEFAULT_NUM_COFUNC_NON_DP_DISPLAYS = 2
-+};
-+
-+/*
-+ * get_feature_entries_num
-+ *
-+ * Get number of feature entries
-+ */
-+static inline uint32_t get_feature_entries_num(void)
-+{
-+ return ARRAY_SIZE(feature_entry_table);
-+}
-+
-+static void get_platform_info_methods(
-+ struct adapter_service *as)
-+{
-+ struct platform_info_params params;
-+ uint32_t mask = 0;
-+
-+ params.data = &mask;
-+ params.method = PM_GET_AVAILABLE_METHODS;
-+
-+ if (dal_get_platform_info(as->ctx, &params))
-+ as->platform_methods_mask = mask;
-+
-+
-+}
-+
-+static void initialize_backlight_caps(
-+ struct adapter_service *as)
-+{
-+ struct firmware_info fw_info;
-+ struct embedded_panel_info panel_info;
-+ struct platform_info_ext_brightness_caps caps;
-+ struct platform_info_params params;
-+ bool custom_curve_present = false;
-+ bool custom_min_max_present = false;
-+
-+ if (!(PM_GET_EXTENDED_BRIGHNESS_CAPS & as->platform_methods_mask)) {
-+ dal_logger_write(as->ctx->logger,
-+ LOG_MAJOR_BACKLIGHT,
-+ LOG_MINOR_BACKLIGHT_BRIGHTESS_CAPS,
-+ "This method is not supported\n");
-+ return;
-+ }
-+
-+ if (dal_bios_parser_get_firmware_info
-+ (as->bios_parser, &fw_info) != BP_RESULT_OK ||
-+ dal_bios_parser_get_embedded_panel_info
-+ (as->bios_parser, &panel_info) != BP_RESULT_OK)
-+ return;
-+
-+ params.data = &caps;
-+ params.method = PM_GET_EXTENDED_BRIGHNESS_CAPS;
-+
-+ if (dal_get_platform_info(as->ctx, &params)) {
-+ as->ac_level_percentage = caps.basic_caps.ac_level_percentage;
-+ as->dc_level_percentage = caps.basic_caps.dc_level_percentage;
-+ custom_curve_present = (caps.data_points_num > 0);
-+ custom_min_max_present = true;
-+ } else
-+ return;
-+ /* Choose minimum backlight level base on priority:
-+ * extended caps,VBIOS,default */
-+ if (custom_min_max_present)
-+ as->backlight_8bit_lut[0] = caps.min_input_signal;
-+
-+ else if (fw_info.min_allowed_bl_level > 0)
-+ as->backlight_8bit_lut[0] = fw_info.min_allowed_bl_level;
-+
-+ else
-+ as->backlight_8bit_lut[0] = DEFAULT_MIN_BACKLIGHT;
-+
-+ /* Choose maximum backlight level base on priority:
-+ * extended caps,default */
-+ if (custom_min_max_present)
-+ as->backlight_8bit_lut[100] = caps.max_input_signal;
-+
-+ else
-+ as->backlight_8bit_lut[100] = DEFAULT_MAX_BACKLIGHT;
-+
-+ if (as->backlight_8bit_lut[100] > ABSOLUTE_BACKLIGHT_MAX)
-+ as->backlight_8bit_lut[100] = ABSOLUTE_BACKLIGHT_MAX;
-+
-+ if (as->backlight_8bit_lut[0] > as->backlight_8bit_lut[100])
-+ as->backlight_8bit_lut[0] = as->backlight_8bit_lut[100];
-+
-+ if (custom_curve_present) {
-+ uint16_t index = 1;
-+ uint16_t i;
-+ uint16_t num_of_data_points = (caps.data_points_num <= 99 ?
-+ caps.data_points_num : 99);
-+ /* Filling translation table from data points -
-+ * between every two provided data points we
-+ * lineary interpolate missing values
-+ */
-+ for (i = 0 ; i < num_of_data_points; i++) {
-+ uint16_t luminance = caps.data_points[i].luminance;
-+ uint16_t signal_level =
-+ caps.data_points[i].signal_level;
-+
-+ if (signal_level < as->backlight_8bit_lut[0])
-+ signal_level = as->backlight_8bit_lut[0];
-+
-+ if (signal_level > as->backlight_8bit_lut[100])
-+ signal_level = as->backlight_8bit_lut[100];
-+
-+ /* Lineary interpolate missing values */
-+ if (index < luminance) {
-+ uint16_t base_value =
-+ as->backlight_8bit_lut[index-1];
-+ uint16_t delta_signal =
-+ signal_level - base_value;
-+ uint16_t delta_luma = luminance - index + 1;
-+ uint16_t step = delta_signal;
-+
-+ for (; index < luminance ; index++) {
-+ as->backlight_8bit_lut[index] =
-+ base_value +
-+ (step / delta_luma);
-+ step += delta_signal;
-+ }
-+ }
-+ /* Now [index == luminance], so we can add
-+ * data point to the translation table */
-+ as->backlight_8bit_lut[index++] = signal_level;
-+ }
-+ /* Complete the final segment of interpolation -
-+ * between last datapoint and maximum value */
-+ if (index < 100) {
-+ uint16_t base_value = as->backlight_8bit_lut[index-1];
-+ uint16_t delta_signal =
-+ as->backlight_8bit_lut[100]-base_value;
-+ uint16_t delta_luma = 100 - index + 1;
-+ uint16_t step = delta_signal;
-+
-+ for (; index < 100 ; index++) {
-+ as->backlight_8bit_lut[index] = base_value +
-+ (step / delta_luma);
-+ step += delta_signal;
-+ }
-+ }
-+ }
-+ /* build backlight translation table based on default curve */
-+ else {
-+ /* Default backlight curve can be defined by
-+ * polinomial F(x) = A(x*x) + Bx + C.
-+ * Backlight curve should always satisfy
-+ * F(0) = min, F(100) = max, so polinomial coefficients are:
-+ * A is 0.0255 - B/100 - min/10000 -
-+ * (255-max)/10000 = (max - min)/10000 - B/100
-+ * B is adjustable factor to modify the curve.
-+ * Bigger B results in less concave curve.
-+ * B range is [0..(max-min)/100]
-+ * C is backlight minimum
-+ */
-+ uint16_t delta = as->backlight_8bit_lut[100] -
-+ as->backlight_8bit_lut[0];
-+ uint16_t coeffc = as->backlight_8bit_lut[0];
-+ uint16_t coeffb = (BACKLIGHT_CURVE_COEFFB < delta ?
-+ BACKLIGHT_CURVE_COEFFB : delta);
-+ uint16_t coeffa = delta - coeffb;
-+ uint16_t i;
-+ uint32_t temp;
-+
-+ for (i = 1; i < 100 ; i++) {
-+ temp = (coeffa * i * i) / BACKLIGHT_CURVE_COEFFA_FACTOR;
-+ as->backlight_8bit_lut[i] = temp + (coeffb * i) /
-+ BACKLIGHT_CURVE_COEFFB_FACTOR + coeffc;
-+ }
-+ }
-+ as->backlight_caps_initialized = true;
-+}
-+
-+static void log_overriden_features(
-+ struct adapter_service *as,
-+ const char *feature_name,
-+ enum adapter_feature_id id,
-+ bool bool_feature,
-+ uint32_t value)
-+{
-+ if (bool_feature)
-+ dal_logger_write(as->ctx->logger,
-+ LOG_MAJOR_FEATURE_OVERRIDE,
-+ LOG_MINOR_FEATURE_OVERRIDE,
-+ "Overridden %s is %s now\n",
-+ feature_name,
-+ (value == 0) ? "disabled" : "enabled");
-+ else
-+ dal_logger_write(as->ctx->logger,
-+ LOG_MAJOR_FEATURE_OVERRIDE,
-+ LOG_MINOR_FEATURE_OVERRIDE,
-+ "Overridden %s new value: %d\n",
-+ feature_name,
-+ value);
-+}
-+
-+/*************************************
-+ * Local static functions definition *
-+ *************************************/
-+
-+#define check_bool_feature(feature) \
-+case FEATURE_ ## feature: \
-+ if (param->bool_param_enable_mask & \
-+ (1 << DAL_PARAM_ ## feature)) { \
-+ *data = param->bool_param_values & \
-+ (1 << DAL_PARAM_ ## feature); \
-+ ret = true; \
-+ feature_name = "FEATURE_" #feature; \
-+ } \
-+ break
-+
-+#define check_int_feature(feature) \
-+case FEATURE_ ## feature: \
-+ if (param->int_param_values[DAL_PARAM_ ## feature] != \
-+ DAL_PARAM_INVALID_INT) { \
-+ *data = param->int_param_values[DAL_PARAM_ ## feature];\
-+ ret = true;\
-+ bool_feature = false;\
-+ feature_name = "FEATURE_" #feature;\
-+ } \
-+ break
-+
-+/*
-+ * override_default_parameters
-+ *
-+ * Override features (from runtime parameter)
-+ * corresponding to Adapter Service Feature ID
-+ */
-+static bool override_default_parameters(
-+ struct adapter_service *as,
-+ const struct dal_override_parameters *param,
-+ const uint32_t idx,
-+ uint32_t *data)
-+{
-+ bool ret = false;
-+ bool bool_feature = true;
-+ char *feature_name;
-+
-+ if (idx >= get_feature_entries_num()) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ switch (feature_entry_table[idx].feature_id) {
-+ check_int_feature(MAX_COFUNC_NON_DP_DISPLAYS);
-+ check_int_feature(DRR_SUPPORT);
-+ check_bool_feature(LIGHT_SLEEP);
-+ check_bool_feature(MAXIMIZE_STUTTER_MARKS);
-+ check_bool_feature(MAXIMIZE_URGENCY_WATERMARKS);
-+ check_bool_feature(USE_MAX_DISPLAY_CLK);
-+ check_bool_feature(ENABLE_DFS_BYPASS);
-+ check_bool_feature(POWER_GATING_PIPE_IN_TILE);
-+ check_bool_feature(POWER_GATING_LB_PORTION);
-+ check_bool_feature(PSR_ENABLE);
-+ check_bool_feature(VARI_BRIGHT_ENABLE);
-+ check_bool_feature(USE_PPLIB);
-+ check_bool_feature(DISABLE_LPT_SUPPORT);
-+ check_bool_feature(DUMMY_FBC_BACKEND);
-+ check_bool_feature(ENABLE_GPU_SCALING);
-+ default:
-+ return false;
-+ }
-+ if (ret)
-+ log_overriden_features(
-+ as,
-+ feature_name,
-+ feature_entry_table[idx].feature_id,
-+ bool_feature,
-+ *data);
-+
-+ return ret;
-+}
-+
-+/*
-+ * get_feature_value_from_data_sources
-+ *
-+ * For a given feature, determine its value from ASIC cap and wireless
-+ * data source.
-+ * idx : index of feature_entry_table for the feature id.
-+ */
-+static bool get_feature_value_from_data_sources(
-+ const struct adapter_service *as,
-+ const uint32_t idx,
-+ uint32_t *data)
-+{
-+ if (idx >= get_feature_entries_num()) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ switch (feature_entry_table[idx].feature_id) {
-+ case FEATURE_MAX_COFUNC_NON_DP_DISPLAYS:
-+ *data = as->asic_cap->data[ASIC_DATA_MAX_COFUNC_NONDP_DISPLAYS];
-+ break;
-+
-+ case FEATURE_WIRELESS_LIMIT_720P:
-+ *data = as->asic_cap->caps.WIRELESS_LIMIT_TO_720P;
-+ break;
-+
-+ case FEATURE_WIRELESS_FULL_TIMING_ADJUSTMENT:
-+ *data = as->asic_cap->caps.WIRELESS_FULL_TIMING_ADJUSTMENT;
-+ break;
-+
-+ case FEATURE_MODIFY_TIMINGS_FOR_WIRELESS:
-+ *data = as->asic_cap->caps.WIRELESS_TIMING_ADJUSTMENT;
-+ break;
-+
-+ case FEATURE_SUPPORTED_HDMI_CONNECTION_NUM:
-+ *data =
-+ as->asic_cap->data[ASIC_DATA_SUPPORTED_HDMI_CONNECTION_NUM];
-+ break;
-+
-+ case FEATURE_DETECT_REQUIRE_HPD_HIGH:
-+ *data = as->asic_cap->caps.HPD_CHECK_FOR_EDID;
-+ break;
-+
-+ case FEATURE_NO_HPD_LOW_POLLING_VCC_OFF:
-+ *data = as->asic_cap->caps.NO_VCC_OFF_HPD_POLLING;
-+ break;
-+
-+ case FEATURE_STUTTER_MODE:
-+ *data = as->asic_cap->data[ASIC_DATA_STUTTERMODE];
-+ break;
-+
-+ case FEATURE_WIRELESS_ENABLE:
-+ *data = as->wireless_data.wireless_enable;
-+ break;
-+
-+ case FEATURE_8BPP_SUPPORTED:
-+ *data = as->asic_cap->caps.SUPPORT_8BPP;
-+ break;
-+
-+ default:
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+/* get_bool_value
-+ *
-+ * Get the boolean value of a given feature
-+ */
-+static bool get_bool_value(
-+ const uint32_t set,
-+ const uint32_t idx)
-+{
-+ if (idx >= 32) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ return ((set & (1 << idx)) != 0);
-+}
-+
-+/*
-+ * get_hpd_info
-+ *
-+ * Get HPD information from BIOS
-+ */
-+static bool get_hpd_info(struct adapter_service *as,
-+ struct graphics_object_id id,
-+ struct graphics_object_hpd_info *info)
-+{
-+ return BP_RESULT_OK ==
-+ dal_bios_parser_get_hpd_info(as->bios_parser, id, info);
-+}
-+
-+/*
-+ * lookup_feature_entry
-+ *
-+ * Find the entry index of a given feature in feature table
-+ */
-+static uint32_t lookup_feature_entry(
-+ enum adapter_feature_id feature_id)
-+{
-+ uint32_t entries_num = get_feature_entries_num();
-+ uint32_t i = 0;
-+
-+ while (i != entries_num) {
-+ if (feature_entry_table[i].feature_id == feature_id)
-+ break;
-+
-+ ++i;
-+ }
-+
-+ return i;
-+}
-+
-+/*
-+ * set_bool_value
-+ *
-+ * Set the boolean value of a given feature
-+ */
-+static void set_bool_value(
-+ uint32_t *set,
-+ const uint32_t idx,
-+ bool value)
-+{
-+ if (idx >= 32) {
-+ ASSERT_CRITICAL(false);
-+ return;
-+ }
-+
-+ if (value)
-+ *set |= (1 << idx);
-+ else
-+ *set &= ~(1 << idx);
-+}
-+
-+/*
-+ * generate_feature_set
-+ *
-+ * Generate the internal feature set from multiple data sources
-+ */
-+static bool generate_feature_set(
-+ struct adapter_service *as,
-+ const struct dal_override_parameters *param)
-+{
-+ uint32_t i = 0;
-+ uint32_t value = 0;
-+ uint32_t set_idx = 0;
-+ uint32_t internal_idx = 0;
-+ uint32_t entry_num = 0;
-+ const struct feature_source_entry *entry = NULL;
-+
-+ dc_service_memset(adapter_feature_set, 0, sizeof(adapter_feature_set));
-+ entry_num = get_feature_entries_num();
-+
-+
-+ while (i != entry_num) {
-+ entry = &feature_entry_table[i];
-+
-+ if (entry->feature_id <= FEATURE_UNKNOWN ||
-+ entry->feature_id >= FEATURE_MAXIMUM) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ set_idx = (uint32_t)((entry->feature_id - 1) / 32);
-+ internal_idx = (uint32_t)((entry->feature_id - 1) % 32);
-+
-+ /* TODO: wireless, runtime parameter, vbios */
-+ if (!override_default_parameters(as, param, i, &value)) {
-+ if (!get_feature_value_from_data_sources(
-+ as, i, &value)) {
-+ /*
-+ * Can't find feature values from
-+ * above data sources
-+ * Assign default value
-+ */
-+ value = entry->default_value;
-+ }
-+ }
-+
-+ if (entry->is_boolean_type)
-+ set_bool_value(&adapter_feature_set[set_idx],
-+ internal_idx,
-+ value != 0);
-+ else
-+ adapter_feature_set[set_idx] = value;
-+
-+ i++;
-+ }
-+
-+ return true;
-+}
-+
-+
-+/*
-+ * create_hw_ctx
-+ *
-+ * Create HW context for adapter service. This is DCE specific.
-+ */
-+static struct hw_ctx_adapter_service *create_hw_ctx(
-+ enum dce_version dce_version,
-+ struct dc_context *ctx)
-+{
-+ switch (dce_version) {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ case DCE_VERSION_11_0:
-+ return dal_adapter_service_create_hw_ctx_dce110(ctx);
-+#endif
-+ default:
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+}
-+
-+/*
-+ * adapter_service_destruct
-+ *
-+ * Release memory of objects in adapter service
-+ */
-+static void adapter_service_destruct(
-+ struct adapter_service *as)
-+{
-+ dal_adapter_service_destroy_hw_ctx(&as->hw_ctx);
-+ dal_i2caux_destroy(&as->i2caux);
-+ dal_bios_parser_destroy(&as->bios_parser);
-+ dal_gpio_service_destroy(&as->gpio_service);
-+ dal_asic_capability_destroy(&as->asic_cap);
-+ dal_bios_parser_destroy_integrated_info(as->ctx, &as->integrated_info);
-+}
-+
-+/*
-+ * adapter_service_construct
-+ *
-+ * Construct the derived type of adapter service
-+ */
-+static bool adapter_service_construct(
-+ struct adapter_service *as,
-+ struct as_init_data *init_data)
-+{
-+ if (!init_data)
-+ return false;
-+
-+ /* Create ASIC capability */
-+ as->ctx = init_data->ctx;
-+ as->asic_cap = dal_asic_capability_create(
-+ &init_data->hw_init_data, as->ctx);
-+
-+ if (!as->asic_cap) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+#if defined(DAL_CZ_BRINGUP)
-+ if (dal_adapter_service_get_dce_version(as) == DCE_VERSION_11_0) {
-+ uint32_t i;
-+
-+ for (i = 0; i < ARRAY_SIZE(feature_entry_table); i++) {
-+ enum adapter_feature_id id =
-+ feature_entry_table[i].feature_id;
-+ if (id == FEATURE_MAXIMIZE_URGENCY_WATERMARKS ||
-+ id == FEATURE_MAXIMIZE_STUTTER_MARKS ||
-+ id == FEATURE_MAXIMIZE_NBP_MARKS)
-+ feature_entry_table[i].default_value = true;
-+ }
-+ }
-+#endif
-+
-+ /* Generate feature set table */
-+ if (!generate_feature_set(as, init_data->display_param)) {
-+ ASSERT_CRITICAL(false);
-+ goto failed_to_generate_features;
-+ }
-+
-+ /* Create BIOS parser */
-+ init_data->bp_init_data.ctx = init_data->ctx;
-+ as->bios_parser =
-+ dal_bios_parser_create(&init_data->bp_init_data, as);
-+
-+ if (!as->bios_parser) {
-+ ASSERT_CRITICAL(false);
-+ goto failed_to_create_bios_parser;
-+ }
-+
-+ /* Create GPIO service */
-+ as->gpio_service =
-+ dal_gpio_service_create(
-+ dal_adapter_service_get_dce_version(as),
-+ as->ctx);
-+
-+ if (!as->gpio_service) {
-+ ASSERT_CRITICAL(false);
-+ goto failed_to_create_gpio_service;
-+ }
-+
-+ /* Create I2C AUX */
-+ as->i2caux = dal_i2caux_create(as, as->ctx);
-+
-+ if (!as->i2caux) {
-+ ASSERT_CRITICAL(false);
-+ goto failed_to_create_i2caux;
-+ }
-+
-+ /* Create Adapter Service HW Context*/
-+ as->hw_ctx = create_hw_ctx(
-+ dal_adapter_service_get_dce_version(as),
-+ as->ctx);
-+
-+ if (!as->hw_ctx) {
-+ ASSERT_CRITICAL(false);
-+ goto failed_to_create_hw_ctx;
-+ }
-+
-+ /* Avoid wireless encoder creation in upstream branch. */
-+
-+ /* Integrated info is not provided on discrete ASIC. NULL is allowed */
-+ as->integrated_info = dal_bios_parser_create_integrated_info(
-+ as->bios_parser);
-+
-+ dal_bios_parser_post_init(as->bios_parser);
-+
-+ /* Generate backlight translation table and initializes
-+ other brightness properties */
-+ as->backlight_caps_initialized = false;
-+
-+ get_platform_info_methods(as);
-+
-+ initialize_backlight_caps(as);
-+
-+ return true;
-+
-+failed_to_generate_features:
-+ dal_adapter_service_destroy_hw_ctx(&as->hw_ctx);
-+
-+failed_to_create_hw_ctx:
-+ dal_i2caux_destroy(&as->i2caux);
-+
-+failed_to_create_i2caux:
-+ dal_gpio_service_destroy(&as->gpio_service);
-+
-+failed_to_create_gpio_service:
-+ dal_bios_parser_destroy(&as->bios_parser);
-+
-+failed_to_create_bios_parser:
-+ dal_asic_capability_destroy(&as->asic_cap);
-+
-+ return false;
-+}
-+
-+/*
-+ * Global function definition
-+ */
-+
-+/*
-+ * dal_adapter_service_create
-+ *
-+ * Create adapter service
-+ */
-+struct adapter_service *dal_adapter_service_create(
-+ struct as_init_data *init_data)
-+{
-+ struct adapter_service *as;
-+
-+ as = dc_service_alloc(init_data->ctx, sizeof(struct adapter_service));
-+
-+ if (!as) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ if (adapter_service_construct(as, init_data))
-+ return as;
-+
-+ ASSERT_CRITICAL(false);
-+
-+ dc_service_free(init_data->ctx, as);
-+
-+ return NULL;
-+}
-+
-+/*
-+ * dal_adapter_service_destroy
-+ *
-+ * Destroy adapter service and objects it contains
-+ */
-+void dal_adapter_service_destroy(
-+ struct adapter_service **as)
-+{
-+ if (!as) {
-+ ASSERT_CRITICAL(false);
-+ return;
-+ }
-+
-+ if (!*as) {
-+ ASSERT_CRITICAL(false);
-+ return;
-+ }
-+
-+ adapter_service_destruct(*as);
-+
-+ dc_service_free((*as)->ctx, *as);
-+
-+ *as = NULL;
-+}
-+
-+/*
-+ * dal_adapter_service_get_dce_version
-+ *
-+ * Get the DCE version of current ASIC
-+ */
-+enum dce_version dal_adapter_service_get_dce_version(
-+ const struct adapter_service *as)
-+{
-+ uint32_t version = as->asic_cap->data[ASIC_DATA_DCE_VERSION];
-+
-+ switch (version) {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ case 0x110:
-+ return DCE_VERSION_11_0;
-+#endif
-+ default:
-+ ASSERT_CRITICAL(false);
-+ return DCE_VERSION_UNKNOWN;
-+ }
-+}
-+
-+/*
-+ * dal_adapter_service_get_controllers_num
-+ *
-+ * Get number of controllers
-+ */
-+uint8_t dal_adapter_service_get_controllers_num(
-+ struct adapter_service *as)
-+{
-+ uint32_t result = as->asic_cap->data[ASIC_DATA_CONTROLLERS_NUM];
-+
-+ /* Check the "max num of controllers" feature,
-+ * use it for debugging purposes only */
-+ /* TODO implement
-+ * dal_adapter_service_get_feature_value(as, ) */
-+
-+ return result;
-+}
-+
-+
-+/** Get total number of connectors.
-+ *
-+ * \param as Adapter Service
-+ *
-+ * \return Total number of connectors. It is up-to-the caller to decide
-+ * if the number is valid.
-+ */
-+uint8_t dal_adapter_service_get_connectors_num(
-+ struct adapter_service *as)
-+{
-+ uint8_t vbios_connectors_num = 0;
-+ uint8_t wireless_connectors_num = 0;
-+
-+ vbios_connectors_num = dal_bios_parser_get_connectors_number(
-+ as->bios_parser);
-+ wireless_connectors_num = wireless_get_connectors_num(as);
-+
-+ return vbios_connectors_num + wireless_connectors_num;
-+}
-+
-+static bool is_wireless_object(struct graphics_object_id id)
-+{
-+ if ((id.type == OBJECT_TYPE_ENCODER &&
-+ id.id == ENCODER_ID_INTERNAL_WIRELESS) ||
-+ (id.type == OBJECT_TYPE_CONNECTOR && id.id ==
-+ CONNECTOR_ID_WIRELESS) ||
-+ (id.type == OBJECT_TYPE_CONNECTOR && id.id ==
-+ CONNECTOR_ID_MIRACAST))
-+ return true;
-+ return false;
-+}
-+
-+/**
-+ * Get the number of source objects of an object
-+ *
-+ * \param [in] as: Adapter Service
-+ *
-+ * \param [in] id: The graphics object id
-+ *
-+ * \return
-+ * The number of the source objects of an object
-+ */
-+uint32_t dal_adapter_service_get_src_num(
-+ struct adapter_service *as, struct graphics_object_id id)
-+{
-+ if (is_wireless_object(id))
-+ return wireless_get_srcs_num(as, id);
-+ else
-+ return dal_bios_parser_get_src_number(as->bios_parser, id);
-+}
-+
-+/**
-+ * Get the source objects of an object
-+ *
-+ * \param [in] id The graphics object id
-+ * \param [in] index Enumerating index which starts at 0
-+ *
-+ * \return If enumerating successfully, return the VALID source object id,
-+ * otherwise, returns "zeroed out" object id.
-+ * Client should call dal_graphics_object_id_is_valid() to check
-+ * weather the id is valid.
-+ */
-+struct graphics_object_id dal_adapter_service_get_src_obj(
-+ struct adapter_service *as,
-+ struct graphics_object_id id,
-+ uint32_t index)
-+{
-+ struct graphics_object_id src_object_id;
-+
-+ if (is_wireless_object(id))
-+ src_object_id = wireless_get_src_obj_id(as, id, index);
-+ else {
-+ if (BP_RESULT_OK !=
-+ dal_bios_parser_get_src_obj(
-+ as->bios_parser, id, index, &src_object_id))
-+ src_object_id =
-+ dal_graphics_object_id_init(
-+ 0,
-+ ENUM_ID_UNKNOWN,
-+ OBJECT_TYPE_UNKNOWN);
-+ }
-+
-+ return src_object_id;
-+}
-+
-+/** Get connector object id associated with a connector index.
-+ *
-+ * \param as Adapter Service
-+ *
-+ * \param connector_index Index of connector between zero and total number
-+ * returned by dal_adapter_service_get_connectors_num()
-+ *
-+ * \return graphics object id corresponding to the connector_index.
-+ */
-+struct graphics_object_id dal_adapter_service_get_connector_obj_id(
-+ struct adapter_service *as,
-+ uint8_t connector_index)
-+{
-+ uint8_t bios_connectors_num =
-+ dal_bios_parser_get_connectors_number(as->bios_parser);
-+
-+ if (connector_index >= bios_connectors_num)
-+ return wireless_get_connector_id(
-+ as,
-+ connector_index);
-+ else
-+ return dal_bios_parser_get_connector_id(
-+ as->bios_parser,
-+ connector_index);
-+}
-+
-+bool dal_adapter_service_get_device_tag(
-+ struct adapter_service *as,
-+ struct graphics_object_id connector_object_id,
-+ uint32_t device_tag_index,
-+ struct connector_device_tag_info *info)
-+{
-+ if (BP_RESULT_OK == dal_bios_parser_get_device_tag(as->bios_parser,
-+ connector_object_id, device_tag_index, info))
-+ return true;
-+ else
-+ return false;
-+}
-+
-+/* Check if DeviceId is supported by ATOM_OBJECT_HEADER support info */
-+bool dal_adapter_service_is_device_id_supported(struct adapter_service *as,
-+ struct device_id id)
-+{
-+ return dal_bios_parser_is_device_id_supported(as->bios_parser, id);
-+}
-+
-+bool dal_adapter_service_is_meet_underscan_req(struct adapter_service *as)
-+{
-+ struct firmware_info fw_info;
-+ enum bp_result bp_result = dal_adapter_service_get_firmware_info(
-+ as, &fw_info);
-+ uint32_t disp_clk_limit =
-+ as->asic_cap->data[ASIC_DATA_MIN_DISPCLK_FOR_UNDERSCAN];
-+ if (BP_RESULT_OK == bp_result) {
-+ dal_logger_write(as->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_ADAPTER_SERVICE,
-+ "Read firmware is NULL");
-+ return false;
-+ }
-+ if (fw_info.default_display_engine_pll_frequency < disp_clk_limit)
-+ return false;
-+ return true;
-+}
-+
-+bool dal_adapter_service_underscan_for_hdmi_only(struct adapter_service *as)
-+{
-+ return as->asic_cap->caps.UNDERSCAN_FOR_HDMI_ONLY;
-+}
-+/*
-+ * dal_adapter_service_get_clock_sources_num
-+ *
-+ * Get number of clock sources
-+ */
-+uint8_t dal_adapter_service_get_clock_sources_num(
-+ struct adapter_service *as)
-+{
-+ struct firmware_info fw_info;
-+ uint32_t max_clk_src = 0;
-+ uint32_t num = as->asic_cap->data[ASIC_DATA_CLOCKSOURCES_NUM];
-+
-+ /*
-+ * Check is system supports the use of the External clock source
-+ * as a clock source for DP
-+ */
-+ enum bp_result bp_result =
-+ dal_bios_parser_get_firmware_info(as->bios_parser,
-+ &fw_info);
-+
-+ if (BP_RESULT_OK == bp_result &&
-+ fw_info.external_clock_source_frequency_for_dp != 0)
-+ ++num;
-+
-+ /*
-+ * Add clock source for wireless if supported
-+ */
-+ num += (uint32_t)wireless_get_clocks_num(as);
-+
-+ /* Check the "max number of clock sources" feature */
-+ if (dal_adapter_service_get_feature_value(
-+ FEATURE_MAX_CLOCK_SOURCE_NUM,
-+ &max_clk_src,
-+ sizeof(uint32_t)))
-+ if ((max_clk_src != 0) && (max_clk_src < num))
-+ num = max_clk_src;
-+
-+ return num;
-+}
-+
-+/*
-+ * dal_adapter_service_get_func_controllers_num
-+ *
-+ * Get number of controllers
-+ */
-+uint8_t dal_adapter_service_get_func_controllers_num(
-+ struct adapter_service *as)
-+{
-+ uint32_t result =
-+ as->asic_cap->data[ASIC_DATA_FUNCTIONAL_CONTROLLERS_NUM];
-+
-+ /* Check the "max num of controllers" feature,
-+ * use it for debugging purposes only */
-+
-+ /* Limit number of controllers by OS */
-+
-+ struct asic_feature_flags flags;
-+
-+ flags.raw = as->asic_cap->data[ASIC_DATA_FEATURE_FLAGS];
-+
-+ if (flags.bits.LEGACY_CLIENT &&
-+ (result > LEGACY_MAX_NUM_OF_CONTROLLERS))
-+ result = LEGACY_MAX_NUM_OF_CONTROLLERS;
-+
-+ return result;
-+}
-+
-+/*
-+ * dal_adapter_service_is_feature_supported
-+ *
-+ * Return if a given feature is supported by the ASIC. The feature has to be
-+ * a boolean type.
-+ */
-+bool dal_adapter_service_is_feature_supported(
-+ enum adapter_feature_id feature_id)
-+{
-+ bool data = 0;
-+
-+ dal_adapter_service_get_feature_value(feature_id, &data, sizeof(bool));
-+
-+ return data;
-+}
-+
-+/**
-+ * Reports maximum number of confunctional non-DP displays.
-+ * Value can be overriden if FEATURE_REPORT_SINGLE_SELECTED_TIMING feature is
-+ * enabled.
-+ *
-+ * \return
-+ * Maximum number of confunctional non-DP displays
-+ */
-+uint32_t dal_adapter_service_get_max_cofunc_non_dp_displays(void)
-+{
-+ uint32_t non_dp_displays = DEFAULT_NUM_COFUNC_NON_DP_DISPLAYS;
-+
-+ if (true == dal_adapter_service_get_feature_value(
-+ FEATURE_MAX_COFUNC_NON_DP_DISPLAYS,
-+ &non_dp_displays,
-+ sizeof(non_dp_displays))) {
-+ /* the cached value exist */
-+ /* TODO: add more logic as per-DAL2 */
-+ }
-+
-+ return non_dp_displays;
-+}
-+
-+uint32_t dal_adapter_service_get_single_selected_timing_signals(void)
-+{
-+ uint32_t signals_bitmap = 0;
-+
-+ if (dal_adapter_service_is_feature_supported(
-+ FEATURE_REPORT_SINGLE_SELECTED_TIMING)) {
-+ /* the cached value exist */
-+ /* TODO: add more logic as per-DAL2 */
-+ signals_bitmap = 0;
-+ }
-+
-+ return signals_bitmap;
-+}
-+
-+/*
-+ * dal_adapter_service_get_i2c_info
-+ *
-+ * Get I2C information from BIOS
-+ */
-+bool dal_adapter_service_get_i2c_info(
-+ struct adapter_service *as,
-+ struct graphics_object_id id,
-+ struct graphics_object_i2c_info *i2c_info)
-+{
-+ if (!i2c_info) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ return BP_RESULT_OK ==
-+ dal_bios_parser_get_i2c_info(as->bios_parser, id, i2c_info);
-+}
-+
-+/*
-+ * dal_adapter_service_obtain_ddc
-+ *
-+ * Obtain DDC
-+ */
-+struct ddc *dal_adapter_service_obtain_ddc(
-+ struct adapter_service *as,
-+ struct graphics_object_id id)
-+{
-+ struct graphics_object_i2c_info i2c_info;
-+ struct gpio_ddc_hw_info hw_info;
-+
-+
-+ if (!dal_adapter_service_get_i2c_info(as, id, &i2c_info))
-+ return NULL;
-+
-+ hw_info.ddc_channel = i2c_info.i2c_line;
-+ hw_info.hw_supported = i2c_info.i2c_hw_assist;
-+
-+ return dal_gpio_service_create_ddc(
-+ as->gpio_service,
-+ i2c_info.gpio_info.clk_a_register_index,
-+ 1 << i2c_info.gpio_info.clk_a_shift,
-+ &hw_info);
-+}
-+
-+/*
-+ * dal_adapter_service_release_ddc
-+ *
-+ * Release DDC
-+ */
-+void dal_adapter_service_release_ddc(
-+ struct adapter_service *as,
-+ struct ddc *ddc)
-+{
-+ dal_gpio_service_destroy_ddc(&ddc);
-+}
-+
-+/*
-+ * dal_adapter_service_obtain_hpd_irq
-+ *
-+ * Obtain HPD interrupt request
-+ */
-+struct irq *dal_adapter_service_obtain_hpd_irq(
-+ struct adapter_service *as,
-+ struct graphics_object_id id)
-+{
-+ enum bp_result bp_result;
-+
-+ struct graphics_object_hpd_info hpd_info;
-+ struct gpio_pin_info pin_info;
-+
-+ if (!get_hpd_info(as, id, &hpd_info))
-+ return NULL;
-+
-+ bp_result = dal_bios_parser_get_gpio_pin_info(as->bios_parser,
-+ hpd_info.hpd_int_gpio_uid, &pin_info);
-+
-+ if (bp_result != BP_RESULT_OK) {
-+ ASSERT(bp_result == BP_RESULT_NORECORD);
-+ return NULL;
-+ }
-+
-+ return dal_gpio_service_create_irq(
-+ as->gpio_service,
-+ pin_info.offset,
-+ pin_info.mask);
-+}
-+
-+/*
-+ * dal_adapter_service_release_irq
-+ *
-+ * Release interrupt request
-+ */
-+void dal_adapter_service_release_irq(
-+ struct adapter_service *as,
-+ struct irq *irq)
-+{
-+ dal_gpio_service_destroy_irq(&irq);
-+}
-+
-+/*
-+ * dal_adapter_service_get_ss_info_num
-+ *
-+ * Get number of spread spectrum entries from BIOS
-+ */
-+uint32_t dal_adapter_service_get_ss_info_num(
-+ struct adapter_service *as,
-+ enum as_signal_type signal)
-+{
-+ return dal_bios_parser_get_ss_entry_number(as->bios_parser, signal);
-+}
-+
-+/*
-+ * dal_adapter_service_get_ss_info
-+ *
-+ * Get spread spectrum info from BIOS
-+ */
-+bool dal_adapter_service_get_ss_info(
-+ struct adapter_service *as,
-+ enum as_signal_type signal,
-+ uint32_t idx,
-+ struct spread_spectrum_info *info)
-+{
-+ enum bp_result bp_result =
-+ dal_bios_parser_get_spread_spectrum_info(
-+ as->bios_parser, signal, idx, info);
-+
-+ return BP_RESULT_OK == bp_result;
-+}
-+
-+/*
-+ * dal_adapter_service_get_integrated_info
-+ *
-+ * Get integrated information on BIOS
-+ */
-+bool dal_adapter_service_get_integrated_info(
-+ struct adapter_service *as,
-+ struct integrated_info *info)
-+{
-+ if (info == NULL || as->integrated_info == NULL)
-+ return false;
-+
-+ dc_service_memmove(info, as->integrated_info, sizeof(struct integrated_info));
-+
-+ return true;
-+}
-+
-+/*
-+ * dal_adapter_service_is_dfs_bypass_enabled
-+ *
-+ * Check if DFS bypass is enabled
-+ */
-+bool dal_adapter_service_is_dfs_bypass_enabled(
-+ struct adapter_service *as)
-+{
-+ if (as->integrated_info == NULL)
-+ return false;
-+ if ((as->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) &&
-+ dal_adapter_service_is_feature_supported(
-+ FEATURE_ENABLE_DFS_BYPASS))
-+ return true;
-+ else
-+ return false;
-+}
-+
-+/*
-+ * dal_adapter_service_get_sw_i2c_speed
-+ *
-+ * Get SW I2C speed
-+ */
-+uint32_t dal_adapter_service_get_sw_i2c_speed(
-+ struct adapter_service *as)
-+{
-+ /* TODO: only from ASIC caps. Feature key is not implemented*/
-+ return as->asic_cap->data[ASIC_DATA_DEFAULT_I2C_SPEED_IN_KHZ];
-+}
-+
-+/*
-+ * dal_adapter_service_get_hw_i2c_speed
-+ *
-+ * Get HW I2C speed
-+ */
-+uint32_t dal_adapter_service_get_hw_i2c_speed(
-+ struct adapter_service *as)
-+{
-+ /* TODO: only from ASIC caps. Feature key is not implemented*/
-+ return as->asic_cap->data[ASIC_DATA_DEFAULT_I2C_SPEED_IN_KHZ];
-+}
-+
-+/*
-+ * dal_adapter_service_get_mc_latency
-+ *
-+ * Get memory controller latency
-+ */
-+uint32_t dal_adapter_service_get_mc_latency(
-+ struct adapter_service *as)
-+{
-+ return as->asic_cap->data[ASIC_DATA_MC_LATENCY];
-+}
-+
-+/*
-+ * dal_adapter_service_get_asic_vram_bit_width
-+ *
-+ * Get the video RAM bit width set on the ASIC
-+ */
-+uint32_t dal_adapter_service_get_asic_vram_bit_width(
-+ struct adapter_service *as)
-+{
-+ return as->asic_cap->data[ASIC_DATA_VRAM_BITWIDTH];
-+}
-+
-+/*
-+ * dal_adapter_service_get_asic_bugs
-+ *
-+ * Get the bug flags set on this ASIC
-+ */
-+struct asic_bugs dal_adapter_service_get_asic_bugs(
-+ struct adapter_service *as)
-+{
-+ return as->asic_cap->bugs;
-+}
-+
-+
-+struct dal_asic_runtime_flags dal_adapter_service_get_asic_runtime_flags(
-+ struct adapter_service *as)
-+{
-+ return as->asic_cap->runtime_flags;
-+}
-+
-+/*
-+ * dal_adapter_service_get_line_buffer_size
-+ *
-+ * Get line buffer size
-+ */
-+uint32_t dal_adapter_service_get_line_buffer_size(
-+ struct adapter_service *as)
-+{
-+ return as->asic_cap->data[ASIC_DATA_LINEBUFFER_SIZE];
-+}
-+
-+/*
-+ * dal_adapter_service_get_bandwidth_tuning_params
-+ *
-+ * Get parameters for bandwidth tuning
-+ */
-+bool dal_adapter_service_get_bandwidth_tuning_params(
-+ struct adapter_service *as,
-+ union bandwidth_tuning_params *params)
-+{
-+ /* TODO: add implementation */
-+ /* note: data comes from runtime parameters */
-+ return false;
-+}
-+
-+/*
-+ * dal_adapter_service_get_feature_flags
-+ *
-+ * Get a copy of ASIC feature flags
-+ */
-+struct asic_feature_flags dal_adapter_service_get_feature_flags(
-+ struct adapter_service *as)
-+{
-+ struct asic_feature_flags result = { { 0 } };
-+
-+ if (!as) {
-+ ASSERT_CRITICAL(false);
-+ return result;
-+ }
-+
-+ result.raw = as->asic_cap->data[ASIC_DATA_FEATURE_FLAGS];
-+
-+ return result;
-+}
-+
-+/*
-+ * dal_adapter_service_get_dram_bandwidth_efficiency
-+ *
-+ * Get efficiency of DRAM
-+ */
-+uint32_t dal_adapter_service_get_dram_bandwidth_efficiency(
-+ struct adapter_service *as)
-+{
-+ return as->asic_cap->data[ASIC_DATA_DRAM_BANDWIDTH_EFFICIENCY];
-+}
-+
-+/*
-+ * dal_adapter_service_obtain_gpio
-+ *
-+ * Obtain GPIO
-+ */
-+struct gpio *dal_adapter_service_obtain_gpio(
-+ struct adapter_service *as,
-+ enum gpio_id id,
-+ uint32_t en)
-+{
-+ return dal_gpio_service_create_gpio_ex(
-+ as->gpio_service, id, en,
-+ GPIO_PIN_OUTPUT_STATE_DEFAULT);
-+}
-+
-+/*
-+ * dal_adapter_service_obtain_stereo_gpio
-+ *
-+ * Obtain GPIO for stereo3D
-+ */
-+struct gpio *dal_adapter_service_obtain_stereo_gpio(
-+ struct adapter_service *as)
-+{
-+ const bool have_param_stereo_gpio = false;
-+
-+ struct asic_feature_flags result;
-+
-+ result.raw = as->asic_cap->data[ASIC_DATA_FEATURE_FLAGS];
-+
-+ /* Case 1 : Workstation stereo */
-+ if (result.bits.WORKSTATION_STEREO)
-+ /* "active low" <--> "default 3d right eye polarity" = false */
-+ return dal_gpio_service_create_gpio_ex(
-+ as->gpio_service, GPIO_ID_GENERIC, GPIO_GENERIC_A,
-+ GPIO_PIN_OUTPUT_STATE_ACTIVE_LOW);
-+ /* Case 2 : runtime parameter override for sideband stereo */
-+ else if (have_param_stereo_gpio) {
-+ /* TODO implement */
-+ return NULL;
-+ /* Case 3 : VBIOS gives us GPIO for sideband stereo */
-+ } else {
-+ const struct graphics_object_id id =
-+ dal_graphics_object_id_init(
-+ GENERIC_ID_STEREO,
-+ ENUM_ID_1,
-+ OBJECT_TYPE_GENERIC);
-+
-+ struct bp_gpio_cntl_info cntl_info;
-+ struct gpio_pin_info pin_info;
-+
-+ /* Get GPIO record for this object.
-+ * Stereo GPIO record should have exactly one entry
-+ * where active state defines stereosync polarity */
-+ if (1 != dal_bios_parser_get_gpio_record(
-+ as->bios_parser, id, &cntl_info, 1)) {
-+ return NULL;
-+ } else if (BP_RESULT_OK != dal_bios_parser_get_gpio_pin_info(
-+ as->bios_parser, cntl_info.id, &pin_info)) {
-+ /*ASSERT_CRITICAL(false);*/
-+ return NULL;
-+ } else
-+ return dal_gpio_service_create_gpio_ex(
-+ as->gpio_service,
-+ pin_info.offset, pin_info.mask,
-+ cntl_info.state);
-+ }
-+}
-+
-+/*
-+ * dal_adapter_service_release_gpio
-+ *
-+ * Release GPIO
-+ */
-+void dal_adapter_service_release_gpio(
-+ struct adapter_service *as,
-+ struct gpio *gpio)
-+{
-+ dal_gpio_service_destroy_gpio(&gpio);
-+}
-+
-+/*
-+ * dal_adapter_service_get_firmware_info
-+ *
-+ * Get firmware information from BIOS
-+ */
-+bool dal_adapter_service_get_firmware_info(
-+ struct adapter_service *as,
-+ struct firmware_info *info)
-+{
-+ return dal_bios_parser_get_firmware_info(as->bios_parser, info) ==
-+ BP_RESULT_OK;
-+}
-+
-+/*
-+ * dal_adapter_service_get_audio_support
-+ *
-+ * Get information on audio support
-+ */
-+union audio_support dal_adapter_service_get_audio_support(
-+ struct adapter_service *as)
-+{
-+ return dal_adapter_service_hw_ctx_get_audio_support(as->hw_ctx);
-+}
-+
-+/*
-+ * dal_adapter_service_get_stream_engines_num
-+ *
-+ * Get number of stream engines
-+ */
-+uint8_t dal_adapter_service_get_stream_engines_num(
-+ struct adapter_service *as)
-+{
-+ return as->asic_cap->data[ASIC_DATA_DIGFE_NUM];
-+}
-+
-+/*
-+ * dal_adapter_service_get_feature_value
-+ *
-+ * Get the cached value of a given feature. This value can be a boolean, int,
-+ * or characters.
-+ */
-+bool dal_adapter_service_get_feature_value(
-+ const enum adapter_feature_id feature_id,
-+ void *data,
-+ uint32_t size)
-+{
-+ uint32_t entry_idx = 0;
-+ uint32_t set_idx = 0;
-+ uint32_t set_internal_idx = 0;
-+
-+ if (feature_id >= FEATURE_MAXIMUM || feature_id <= FEATURE_UNKNOWN) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ if (data == NULL) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ entry_idx = lookup_feature_entry(feature_id);
-+ set_idx = (uint32_t)((feature_id - 1)/32);
-+ set_internal_idx = (uint32_t)((feature_id - 1) % 32);
-+
-+ if (entry_idx >= get_feature_entries_num()) {
-+ /* Cannot find this entry */
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ if (feature_entry_table[entry_idx].is_boolean_type) {
-+ if (size != sizeof(bool)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ *(bool *)data = get_bool_value(adapter_feature_set[set_idx],
-+ set_internal_idx);
-+ } else {
-+ if (size != sizeof(uint32_t)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ *(uint32_t *)data = adapter_feature_set[set_idx];
-+ }
-+
-+ return true;
-+}
-+
-+/*
-+ * dal_adapter_service_get_memory_type_multiplier
-+ *
-+ * Get multiplier for the memory type
-+ */
-+uint32_t dal_adapter_service_get_memory_type_multiplier(
-+ struct adapter_service *as)
-+{
-+ return as->asic_cap->data[ASIC_DATA_MEMORYTYPE_MULTIPLIER];
-+}
-+
-+/*
-+ * dal_adapter_service_get_bios_parser
-+ *
-+ * Get BIOS parser handler
-+ */
-+struct bios_parser *dal_adapter_service_get_bios_parser(
-+ struct adapter_service *as)
-+{
-+ return as->bios_parser;
-+}
-+
-+/*
-+ * dal_adapter_service_get_i2caux
-+ *
-+ * Get i2c aux handler
-+ */
-+struct i2caux *dal_adapter_service_get_i2caux(
-+ struct adapter_service *as)
-+{
-+ return as->i2caux;
-+}
-+
-+bool dal_adapter_service_initialize_hw_data(
-+ struct adapter_service *as)
-+{
-+ return as->hw_ctx->funcs->power_up(as->hw_ctx);
-+}
-+
-+struct graphics_object_id dal_adapter_service_enum_fake_path_resource(
-+ struct adapter_service *as,
-+ uint32_t index)
-+{
-+ return as->hw_ctx->funcs->enum_fake_path_resource(as->hw_ctx, index);
-+}
-+
-+struct graphics_object_id dal_adapter_service_enum_stereo_sync_object(
-+ struct adapter_service *as,
-+ uint32_t index)
-+{
-+ return as->hw_ctx->funcs->enum_stereo_sync_object(as->hw_ctx, index);
-+}
-+
-+struct graphics_object_id dal_adapter_service_enum_sync_output_object(
-+ struct adapter_service *as,
-+ uint32_t index)
-+{
-+ return as->hw_ctx->funcs->enum_sync_output_object(as->hw_ctx, index);
-+}
-+
-+struct graphics_object_id dal_adapter_service_enum_audio_object(
-+ struct adapter_service *as,
-+ uint32_t index)
-+{
-+ return as->hw_ctx->funcs->enum_audio_object(as->hw_ctx, index);
-+}
-+
-+
-+void dal_adapter_service_update_audio_connectivity(
-+ struct adapter_service *as,
-+ uint32_t number_of_audio_capable_display_path)
-+{
-+ as->hw_ctx->funcs->update_audio_connectivity(
-+ as->hw_ctx,
-+ number_of_audio_capable_display_path,
-+ dal_adapter_service_get_controllers_num(as));
-+}
-+
-+bool dal_adapter_service_has_embedded_display_connector(
-+ struct adapter_service *as)
-+{
-+ uint8_t index;
-+ uint8_t num_connectors = dal_adapter_service_get_connectors_num(as);
-+
-+ if (num_connectors == 0 || num_connectors > ENUM_ID_COUNT)
-+ return false;
-+
-+ for (index = 0; index < num_connectors; index++) {
-+ struct graphics_object_id obj_id =
-+ dal_adapter_service_get_connector_obj_id(as, index);
-+ enum connector_id connector_id =
-+ dal_graphics_object_id_get_connector_id(obj_id);
-+
-+ if ((connector_id == CONNECTOR_ID_LVDS) ||
-+ (connector_id == CONNECTOR_ID_EDP))
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+bool dal_adapter_service_get_embedded_panel_info(
-+ struct adapter_service *as,
-+ struct embedded_panel_info *info)
-+{
-+ enum bp_result result;
-+
-+ if (info == NULL)
-+ /*TODO: add DALASSERT_MSG here*/
-+ return false;
-+
-+ result = dal_bios_parser_get_embedded_panel_info(
-+ as->bios_parser, info);
-+
-+ return result == BP_RESULT_OK;
-+}
-+
-+bool dal_adapter_service_enum_embedded_panel_patch_mode(
-+ struct adapter_service *as,
-+ uint32_t index,
-+ struct embedded_panel_patch_mode *mode)
-+{
-+ enum bp_result result;
-+
-+ if (mode == NULL)
-+ /*TODO: add DALASSERT_MSG here*/
-+ return false;
-+
-+ result = dal_bios_parser_enum_embedded_panel_patch_mode(
-+ as->bios_parser, index, mode);
-+
-+ return result == BP_RESULT_OK;
-+}
-+
-+bool dal_adapter_service_get_faked_edid_len(
-+ struct adapter_service *as,
-+ uint32_t *len)
-+{
-+ enum bp_result result;
-+
-+ result = dal_bios_parser_get_faked_edid_len(
-+ as->bios_parser,
-+ len);
-+ return result == BP_RESULT_OK;
-+}
-+
-+bool dal_adapter_service_get_faked_edid_buf(
-+ struct adapter_service *as,
-+ uint8_t *buf,
-+ uint32_t len)
-+{
-+ enum bp_result result;
-+
-+ result = dal_bios_parser_get_faked_edid_buf(
-+ as->bios_parser,
-+ buf,
-+ len);
-+ return result == BP_RESULT_OK;
-+
-+}
-+
-+/*
-+ * dal_adapter_service_is_fusion
-+ *
-+ * Is this Fusion ASIC
-+ */
-+bool dal_adapter_service_is_fusion(struct adapter_service *as)
-+{
-+ return as->asic_cap->caps.IS_FUSION;
-+}
-+
-+/*
-+ * dal_adapter_service_is_dfsbyass_dynamic
-+ *
-+ *
-+ **/
-+bool dal_adapter_service_is_dfsbyass_dynamic(struct adapter_service *as)
-+{
-+ return as->asic_cap->caps.DFSBYPASS_DYNAMIC_SUPPORT;
-+}
-+
-+/*
-+ * dal_adapter_service_should_optimize
-+ *
-+ * @brief Reports whether driver settings allow requested optimization
-+ *
-+ * @param
-+ * as: adapter service handler
-+ * feature: for which optimization is validated
-+ *
-+ * @return
-+ * true if requested feature can be optimized
-+ */
-+bool dal_adapter_service_should_optimize(
-+ struct adapter_service *as, enum optimization_feature feature)
-+{
-+ uint32_t supported_optimization = 0;
-+ struct dal_asic_runtime_flags flags;
-+
-+ if (!dal_adapter_service_get_feature_value(FEATURE_OPTIMIZATION,
-+ &supported_optimization, sizeof(uint32_t)))
-+ return false;
-+
-+ /* Retrieve ASIC runtime flags */
-+ flags = dal_adapter_service_get_asic_runtime_flags(as);
-+
-+ /* Check runtime flags against different optimization features */
-+ switch (feature) {
-+ case OF_SKIP_HW_PROGRAMMING_ON_ENABLED_EMBEDDED_DISPLAY:
-+ if (!flags.flags.bits.OPTIMIZED_DISPLAY_PROGRAMMING_ON_BOOT)
-+ return false;
-+ break;
-+
-+ case OF_SKIP_RESET_OF_ALL_HW_ON_S3RESUME:
-+ if (as->integrated_info == NULL ||
-+ !flags.flags.bits.SKIP_POWER_DOWN_ON_RESUME)
-+ return false;
-+ break;
-+ case OF_SKIP_POWER_DOWN_INACTIVE_ENCODER:
-+ if (!dal_adapter_service_get_asic_runtime_flags(as).flags.bits.
-+ SKIP_POWER_DOWN_ON_RESUME)
-+ return false;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return (supported_optimization & feature) != 0;
-+}
-+
-+/*
-+ * dal_adapter_service_is_in_accelerated_mode
-+ *
-+ * @brief Determine if driver is in accelerated mode
-+ *
-+ * @param
-+ * as: Adapter Service handler
-+ *
-+ * @out
-+ * True if driver is in accelerated mode, false otherwise.
-+ */
-+bool dal_adapter_service_is_in_accelerated_mode(struct adapter_service *as)
-+{
-+ return dal_bios_parser_is_accelerated_mode(as->bios_parser);
-+}
-+
-+struct ddc *dal_adapter_service_obtain_ddc_from_i2c_info(
-+ struct adapter_service *as,
-+ struct graphics_object_i2c_info *info)
-+{
-+ struct gpio_ddc_hw_info hw_info = {
-+ info->i2c_hw_assist,
-+ info->i2c_line };
-+ return dal_gpio_service_create_ddc(as->gpio_service,
-+ info->gpio_info.clk_a_register_index,
-+ (1 << info->gpio_info.clk_a_shift), &hw_info);
-+}
-+
-+struct bdf_info dal_adapter_service_get_adapter_info(struct adapter_service *as)
-+{
-+ return as->bdf_info;
-+}
-+
-+/*
-+ * dal_adapter_service_should_psr_skip_wait_for_pll_lock
-+ *
-+ * @brief Determine if this ASIC needs to wait on PLL lock bit
-+ *
-+ * @param
-+ * as: Adapter Service handle
-+ *
-+ * @out
-+ * True if ASIC does not need to wait for PLL lock bit, i.e. skip the wait.
-+ */
-+bool dal_adapter_service_should_psr_skip_wait_for_pll_lock(
-+ struct adapter_service *as)
-+{
-+ return as->asic_cap->caps.SKIP_PSR_WAIT_FOR_PLL_LOCK_BIT;
-+}
-+
-+bool dal_adapter_service_is_lid_open(struct adapter_service *as)
-+{
-+ bool is_lid_open = false;
-+ struct platform_info_params params;
-+
-+ params.data = &is_lid_open;
-+ params.method = PM_GET_LID_STATE;
-+
-+ if ((PM_GET_LID_STATE & as->platform_methods_mask) &&
-+ dal_get_platform_info(as->ctx, &params))
-+ return is_lid_open;
-+
-+#if defined(CONFIG_DRM_AMD_DAL_VBIOS_PRESENT)
-+ return dal_bios_parser_is_lid_open(as->bios_parser);
-+#else
-+ return false;
-+#endif
-+}
-+
-+bool dal_adapter_service_get_panel_backlight_default_levels(
-+ struct adapter_service *as,
-+ struct panel_backlight_levels *levels)
-+{
-+ if (!as->backlight_caps_initialized)
-+ return false;
-+
-+ levels->ac_level_percentage = as->ac_level_percentage;
-+ levels->dc_level_percentage = as->dc_level_percentage;
-+ return true;
-+}
-+
-+bool dal_adapter_service_get_panel_backlight_boundaries(
-+ struct adapter_service *as,
-+ struct panel_backlight_boundaries *boundaries)
-+{
-+ if (!as->backlight_caps_initialized)
-+ return false;
-+ if (boundaries != NULL) {
-+ boundaries->min_signal_level = as->backlight_8bit_lut[0];
-+ boundaries->max_signal_level =
-+ as->backlight_8bit_lut[SIZEOF_BACKLIGHT_LUT - 1];
-+ return true;
-+ }
-+ return false;
-+}
-+
-+
-+uint32_t dal_adapter_service_get_view_port_pixel_granularity(
-+ struct adapter_service *as)
-+{
-+ return as->asic_cap->data[ASIC_DATA_VIEWPORT_PIXEL_GRANULARITY];
-+}
-+
-+/**
-+ * Get number of paths per DP 1.2 connector from the runtime parameter if it
-+ * exists.
-+ * A check to see if MST is supported for the generation of ASIC is done
-+ *
-+ * \return
-+ * Number of paths per DP 1.2 connector is exists in runtime parameters
-+ * or ASIC cap
-+ */
-+uint32_t dal_adapter_service_get_num_of_path_per_dp_mst_connector(
-+ struct adapter_service *as)
-+{
-+ if (as->asic_cap->caps.DP_MST_SUPPORTED == 0) {
-+ /* ASIC doesn't support DP MST at all */
-+ return 0;
-+ }
-+
-+ return as->asic_cap->data[ASIC_DATA_PATH_NUM_PER_DPMST_CONNECTOR];
-+}
-+
-+uint32_t dal_adapter_service_get_num_of_underlays(
-+ struct adapter_service *as)
-+{
-+ return as->asic_cap->data[ASIC_DATA_NUM_OF_VIDEO_PLANES];
-+}
-+
-+bool dal_adapter_service_get_encoder_cap_info(
-+ struct adapter_service *as,
-+ struct graphics_object_id id,
-+ struct graphics_object_encoder_cap_info *info)
-+{
-+ struct bp_encoder_cap_info bp_cap_info = {0};
-+ enum bp_result result;
-+
-+ if (NULL == info) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ /*
-+ * Retrieve Encoder Capability Information from VBIOS and store the
-+ * call result (success or fail)
-+ * Info from VBIOS about HBR2 has two fields:
-+ *
-+ * - dpHbr2Cap: indicates supported/not supported by HW Encoder
-+ * - dpHbr2En : indicates DP spec compliant/not compliant
-+ */
-+ result = dal_bios_parser_get_encoder_cap_info(
-+ as->bios_parser,
-+ id,
-+ &bp_cap_info);
-+
-+ /* Set dp_hbr2_validated flag (it's equal to Enable) */
-+ info->dp_hbr2_validated = bp_cap_info.DP_HBR2_EN;
-+
-+ if (result == BP_RESULT_OK) {
-+ info->dp_hbr2_cap = bp_cap_info.DP_HBR2_CAP;
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+bool dal_adapter_service_is_mc_tuning_req(struct adapter_service *as)
-+{
-+ return as->asic_cap->caps.NEED_MC_TUNING ? true : false;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.h b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.h
-new file mode 100644
-index 0000000..25ac648
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.h
-@@ -0,0 +1,67 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_ADAPTER_SERVICE_H__
-+#define __DAL_ADAPTER_SERVICE_H__
-+
-+/* Include */
-+#include "include/adapter_service_interface.h"
-+#include "wireless_data_source.h"
-+
-+/*
-+ * Forward declaration
-+ */
-+struct gpio_service;
-+struct asic_cap;
-+
-+/* Adapter service */
-+struct adapter_service {
-+ struct dc_context *ctx;
-+ struct asic_capability *asic_cap;
-+ struct bios_parser *bios_parser;
-+ struct gpio_service *gpio_service;
-+ struct i2caux *i2caux;
-+ struct wireless_data wireless_data;
-+ struct hw_ctx_adapter_service *hw_ctx;
-+ struct integrated_info *integrated_info;
-+ struct bdf_info bdf_info;
-+ uint32_t platform_methods_mask;
-+ uint32_t ac_level_percentage;
-+ uint32_t dc_level_percentage;
-+ uint32_t backlight_caps_initialized;
-+ uint32_t backlight_8bit_lut[SIZEOF_BACKLIGHT_LUT];
-+};
-+
-+/* Type of feature with its runtime parameter and default value */
-+struct feature_source_entry {
-+ enum adapter_feature_id feature_id;
-+ uint32_t default_value;
-+ bool is_boolean_type;
-+};
-+
-+/* Stores entire ASIC features by sets */
-+extern uint32_t adapter_feature_set[];
-+
-+#endif /* __DAL_ADAPTER_SERVICE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.c b/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.c
-new file mode 100644
-index 0000000..31c2aab
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.c
-@@ -0,0 +1,303 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "../hw_ctx_adapter_service.h"
-+
-+#include "hw_ctx_adapter_service_dce110.h"
-+
-+#include "include/logger_interface.h"
-+#include "include/grph_object_id.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#ifndef mmCC_DC_HDMI_STRAPS
-+#define mmCC_DC_HDMI_STRAPS 0x4819
-+#define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
-+#define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
-+#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
-+#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
-+#endif
-+
-+static const struct graphics_object_id invalid_go = {
-+ 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN, 0
-+};
-+
-+/* Macro */
-+#define AUDIO_STRAPS_HDMI_ENABLE 0x2
-+
-+#define FROM_HW_CTX(ptr) \
-+ container_of((ptr), struct hw_ctx_adapter_service_dce110, base)
-+
-+static const uint32_t audio_index_reg_offset[] = {
-+ /*CZ has 3 DIGs but 4 audio endpoints*/
-+ mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_INDEX
-+};
-+
-+static const uint32_t audio_data_reg_offset[] = {
-+ mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA,
-+ mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_DATA,
-+ mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_DATA,
-+ mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_DATA,
-+};
-+
-+enum {
-+ MAX_NUMBER_OF_AUDIO_PINS = 4
-+};
-+
-+static void destruct(
-+ struct hw_ctx_adapter_service_dce110 *hw_ctx)
-+{
-+ /* There is nothing to destruct at the moment */
-+ dal_adapter_service_destruct_hw_ctx(&hw_ctx->base);
-+}
-+
-+static void destroy(
-+ struct hw_ctx_adapter_service *ptr)
-+{
-+ struct hw_ctx_adapter_service_dce110 *hw_ctx =
-+ FROM_HW_CTX(ptr);
-+
-+ destruct(hw_ctx);
-+
-+ dc_service_free(ptr->ctx, hw_ctx);
-+}
-+
-+/*
-+ * enum_audio_object
-+ *
-+ * @brief enumerate audio object
-+ *
-+ * @param
-+ * const struct hw_ctx_adapter_service *hw_ctx - [in] provides num of endpoints
-+ * uint32_t index - [in] audio index
-+ *
-+ * @return
-+ * grphic object id
-+ */
-+static struct graphics_object_id enum_audio_object(
-+ const struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t index)
-+{
-+ uint32_t number_of_connected_audio_endpoints =
-+ FROM_HW_CTX(hw_ctx)->number_of_connected_audio_endpoints;
-+
-+ if (index >= number_of_connected_audio_endpoints ||
-+ number_of_connected_audio_endpoints == 0)
-+ return invalid_go;
-+ else
-+ return dal_graphics_object_id_init(
-+ AUDIO_ID_INTERNAL_AZALIA,
-+ (enum object_enum_id)(index + 1),
-+ OBJECT_TYPE_AUDIO);
-+}
-+
-+static uint32_t get_number_of_connected_audio_endpoints_multistream(
-+ struct dc_context *ctx)
-+{
-+ uint32_t num_connected_audio_endpoints = 0;
-+ uint32_t i;
-+ uint32_t default_config =
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT;
-+
-+ /* find the total number of streams available via the
-+ * AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT
-+ * registers (one for each pin) starting from pin 1
-+ * up to the max number of audio pins.
-+ * We stop on the first pin where
-+ * PORT_CONNECTIVITY == 1 (as instructed by HW team).
-+ */
-+ for (i = 0; i < MAX_NUMBER_OF_AUDIO_PINS; i++) {
-+ uint32_t value = 0;
-+
-+ set_reg_field_value(value,
-+ default_config,
-+ AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ AZALIA_ENDPOINT_REG_INDEX);
-+
-+ dal_write_reg(ctx, audio_index_reg_offset[i], value);
-+
-+ value = 0;
-+ value = dal_read_reg(ctx, audio_data_reg_offset[i]);
-+
-+ /* 1 means not supported*/
-+ if (get_reg_field_value(value,
-+ AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT,
-+ PORT_CONNECTIVITY) == 1)
-+ break;
-+
-+ num_connected_audio_endpoints++;
-+ }
-+
-+ return num_connected_audio_endpoints;
-+
-+}
-+
-+/*
-+ * get_number_of_connected_audio_endpoints
-+ */
-+static uint32_t get_number_of_connected_audio_endpoints(
-+ struct hw_ctx_adapter_service *hw_ctx)
-+{
-+ uint32_t addr = mmCC_DC_HDMI_STRAPS;
-+ uint32_t value = 0;
-+ uint32_t field = 0;
-+
-+ if (hw_ctx->cached_audio_straps == AUDIO_STRAPS_NOT_ALLOWED)
-+ /* audio straps indicate no audio supported */
-+ return 0;
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+
-+ field = get_reg_field_value(
-+ value, CC_DC_HDMI_STRAPS, AUDIO_STREAM_NUMBER);
-+ if (field == 1)
-+ /* multi streams not supported */
-+ return 1;
-+ else if (field == 0)
-+ /* multi streams supported */
-+ return get_number_of_connected_audio_endpoints_multistream(
-+ hw_ctx->ctx);
-+
-+ /* unexpected value */
-+ ASSERT_CRITICAL(false);
-+ return field;
-+}
-+
-+
-+/*
-+ * power_up
-+ *
-+ * @brief
-+ * Determine and cache audio support from register.
-+ *
-+ * @param
-+ * struct hw_ctx_adapter_service *hw_ctx - [in] adapter service hw context
-+ *
-+ * @return
-+ * true if succeed, false otherwise
-+ */
-+static bool power_up(
-+ struct hw_ctx_adapter_service *hw_ctx)
-+{
-+ struct hw_ctx_adapter_service_dce110 *hw_ctx_dce11 =
-+ FROM_HW_CTX(hw_ctx);
-+ /* Allow DP audio all the time
-+ * without additional pinstrap check on Fusion */
-+
-+
-+ {
-+ uint32_t value = 0;
-+ uint32_t field = 0;
-+
-+ value = dal_read_reg(hw_ctx->ctx, mmCC_DC_HDMI_STRAPS);
-+ field = get_reg_field_value(
-+ value, CC_DC_HDMI_STRAPS, HDMI_DISABLE);
-+
-+ if (field == 0) {
-+ hw_ctx->cached_audio_straps = AUDIO_STRAPS_DP_HDMI_AUDIO;
-+ } else {
-+ value = dal_read_reg(
-+ hw_ctx->ctx, mmDC_PINSTRAPS);
-+ field = get_reg_field_value(
-+ value,
-+ DC_PINSTRAPS,
-+ DC_PINSTRAPS_AUDIO);
-+
-+ if (field & AUDIO_STRAPS_HDMI_ENABLE)
-+ hw_ctx->cached_audio_straps =
-+ AUDIO_STRAPS_DP_HDMI_AUDIO_ON_DONGLE;
-+ else
-+ hw_ctx->cached_audio_straps =
-+ AUDIO_STRAPS_DP_AUDIO_ALLOWED;
-+ }
-+
-+ }
-+
-+ /* get the number of connected audio endpoints */
-+ hw_ctx_dce11->number_of_connected_audio_endpoints =
-+ get_number_of_connected_audio_endpoints(hw_ctx);
-+
-+ return true;
-+}
-+
-+static void update_audio_connectivity(
-+ struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t number_of_audio_capable_display_path,
-+ uint32_t number_of_controllers)
-+{
-+ /* this one should be empty on DCE110 */
-+}
-+
-+static const struct hw_ctx_adapter_service_funcs funcs = {
-+ .destroy = destroy,
-+ .power_up = power_up,
-+ .enum_fake_path_resource = NULL,
-+ .enum_stereo_sync_object = NULL,
-+ .enum_sync_output_object = NULL,
-+ .enum_audio_object = enum_audio_object,
-+ .update_audio_connectivity = update_audio_connectivity
-+};
-+
-+static bool construct(
-+ struct hw_ctx_adapter_service_dce110 *hw_ctx,
-+ struct dc_context *ctx)
-+{
-+ if (!dal_adapter_service_construct_hw_ctx(&hw_ctx->base, ctx)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ hw_ctx->base.funcs = &funcs;
-+ hw_ctx->number_of_connected_audio_endpoints = 0;
-+
-+ return true;
-+}
-+
-+struct hw_ctx_adapter_service *
-+ dal_adapter_service_create_hw_ctx_dce110(
-+ struct dc_context *ctx)
-+{
-+ struct hw_ctx_adapter_service_dce110 *hw_ctx =
-+ dc_service_alloc(ctx, sizeof(struct hw_ctx_adapter_service_dce110));
-+
-+ if (!hw_ctx) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ if (construct(hw_ctx, ctx))
-+ return &hw_ctx->base;
-+
-+ ASSERT_CRITICAL(false);
-+
-+ dc_service_free(ctx, hw_ctx);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.h b/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.h
-new file mode 100644
-index 0000000..092b671
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.h
-@@ -0,0 +1,40 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_CTX_ADAPTER_SERVICE_DCE110_H__
-+#define __DAL_HW_CTX_ADAPTER_SERVICE_DCE110_H__
-+
-+struct hw_ctx_adapter_service_dce110 {
-+ struct hw_ctx_adapter_service base;
-+ uint32_t number_of_connected_audio_endpoints;
-+};
-+
-+struct hw_ctx_adapter_service *
-+ dal_adapter_service_create_hw_ctx_dce110(
-+ struct dc_context *ctx);
-+
-+#endif /* __DAL_HW_CTX_ADAPTER_SERVICE_DCE110_H__ */
-+
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.c b/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.c
-new file mode 100644
-index 0000000..5fa886f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.c
-@@ -0,0 +1,164 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/adapter_service_types.h"
-+#include "include/grph_object_id.h"
-+#include "hw_ctx_adapter_service.h"
-+
-+static const struct graphics_object_id invalid_go = {
-+ 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN
-+};
-+
-+static void destroy(
-+ struct hw_ctx_adapter_service *hw_ctx)
-+{
-+ /* Attention!
-+ * You must override impl method in derived class */
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+static bool power_up(
-+ struct hw_ctx_adapter_service *hw_ctx)
-+{
-+ /* Attention!
-+ * You must override impl method in derived class */
-+ BREAK_TO_DEBUGGER();
-+
-+ return false;
-+}
-+
-+static struct graphics_object_id enum_fake_path_resource(
-+ const struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t index)
-+{
-+ return invalid_go;
-+}
-+
-+static struct graphics_object_id enum_stereo_sync_object(
-+ const struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t index)
-+{
-+ return invalid_go;
-+}
-+
-+static struct graphics_object_id enum_sync_output_object(
-+ const struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t index)
-+{
-+ return invalid_go;
-+}
-+
-+static struct graphics_object_id enum_audio_object(
-+ const struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t index)
-+{
-+ /* by default, we only allow one audio */
-+
-+ if (index > 0)
-+ return invalid_go;
-+ else if (hw_ctx->cached_audio_straps == AUDIO_STRAPS_NOT_ALLOWED)
-+ return invalid_go;
-+ else
-+ return dal_graphics_object_id_init(
-+ AUDIO_ID_INTERNAL_AZALIA,
-+ ENUM_ID_1,
-+ OBJECT_TYPE_AUDIO);
-+}
-+
-+static void update_audio_connectivity(
-+ struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t number_of_audio_capable_display_path,
-+ uint32_t number_of_controllers)
-+{
-+ /* Attention!
-+ * You must override impl method in derived class */
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+static const struct hw_ctx_adapter_service_funcs funcs = {
-+ destroy,
-+ power_up,
-+ enum_fake_path_resource,
-+ enum_stereo_sync_object,
-+ enum_sync_output_object,
-+ enum_audio_object,
-+ update_audio_connectivity
-+};
-+
-+bool dal_adapter_service_construct_hw_ctx(
-+ struct hw_ctx_adapter_service *hw_ctx,
-+ struct dc_context *ctx)
-+{
-+
-+ hw_ctx->ctx = ctx;
-+ hw_ctx->funcs = &funcs;
-+ hw_ctx->cached_audio_straps = AUDIO_STRAPS_NOT_ALLOWED;
-+
-+ return true;
-+}
-+
-+union audio_support dal_adapter_service_hw_ctx_get_audio_support(
-+ const struct hw_ctx_adapter_service *hw_ctx)
-+{
-+ union audio_support result;
-+
-+ result.raw = 0;
-+
-+ switch (hw_ctx->cached_audio_straps) {
-+ case AUDIO_STRAPS_DP_HDMI_AUDIO:
-+ result.bits.HDMI_AUDIO_NATIVE = true;
-+ /* do not break ! */
-+ case AUDIO_STRAPS_DP_HDMI_AUDIO_ON_DONGLE:
-+ result.bits.HDMI_AUDIO_ON_DONGLE = true;
-+ /* do not break ! */
-+ case AUDIO_STRAPS_DP_AUDIO_ALLOWED:
-+ result.bits.DP_AUDIO = true;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return result;
-+}
-+
-+void dal_adapter_service_destruct_hw_ctx(
-+ struct hw_ctx_adapter_service *hw_ctx)
-+{
-+ /* There is nothing to destruct at the moment */
-+}
-+
-+void dal_adapter_service_destroy_hw_ctx(
-+ struct hw_ctx_adapter_service **ptr)
-+{
-+ if (!ptr || !*ptr) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ (*ptr)->funcs->destroy(*ptr);
-+
-+ *ptr = NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.h b/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.h
-new file mode 100644
-index 0000000..f98c2d4
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.h
-@@ -0,0 +1,86 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_CTX_ADAPTER_SERVICE_H__
-+#define __DAL_HW_CTX_ADAPTER_SERVICE_H__
-+
-+enum audio_straps {
-+ AUDIO_STRAPS_NOT_ALLOWED = 0,
-+ AUDIO_STRAPS_DP_AUDIO_ALLOWED,
-+ AUDIO_STRAPS_DP_HDMI_AUDIO_ON_DONGLE,
-+ AUDIO_STRAPS_DP_HDMI_AUDIO
-+};
-+
-+struct hw_ctx_adapter_service;
-+
-+struct hw_ctx_adapter_service_funcs {
-+ void (*destroy)(
-+ struct hw_ctx_adapter_service *hw_ctx);
-+ /* Initializes relevant HW registers
-+ * and caches relevant data from HW registers */
-+ bool (*power_up)(
-+ struct hw_ctx_adapter_service *hw_ctx);
-+ /* Enumerate fake path resources */
-+ struct graphics_object_id (*enum_fake_path_resource)(
-+ const struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t index);
-+ /* Enumerate stereo sync objects */
-+ struct graphics_object_id (*enum_stereo_sync_object)(
-+ const struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t index);
-+ /* Enumerate (H/V) sync output objects */
-+ struct graphics_object_id (*enum_sync_output_object)(
-+ const struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t index);
-+ /* Enumerate audio objects */
-+ struct graphics_object_id (*enum_audio_object)(
-+ const struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t index);
-+ void (*update_audio_connectivity)(
-+ struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t number_of_audio_capable_display_path,
-+ uint32_t number_of_controllers);
-+};
-+
-+struct hw_ctx_adapter_service {
-+ struct dc_context *ctx;
-+ const struct hw_ctx_adapter_service_funcs *funcs;
-+ enum audio_straps cached_audio_straps;
-+};
-+
-+bool dal_adapter_service_construct_hw_ctx(
-+ struct hw_ctx_adapter_service *hw_ctx,
-+ struct dc_context *ctx);
-+
-+union audio_support dal_adapter_service_hw_ctx_get_audio_support(
-+ const struct hw_ctx_adapter_service *hw_ctx);
-+
-+void dal_adapter_service_destruct_hw_ctx(
-+ struct hw_ctx_adapter_service *hw_ctx);
-+
-+void dal_adapter_service_destroy_hw_ctx(
-+ struct hw_ctx_adapter_service **ptr);
-+
-+#endif /* __DAL_HW_CTX_ADAPTER_SERVICE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.c b/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.c
-new file mode 100644
-index 0000000..dcb885d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.c
-@@ -0,0 +1,209 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+
-+#include "dal_services.h"
-+#include "adapter_service.h"
-+#include "wireless_data_source.h"
-+
-+#include "atom.h"
-+
-+/*construct wireless data*/
-+bool wireless_data_init(struct wireless_data *data,
-+ struct bios_parser *bp,
-+ struct wireless_init_data *init_data)
-+{
-+ struct firmware_info info;
-+
-+ if (data == NULL || bp == NULL || init_data == NULL) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ data->miracast_connector_enable = false;
-+ data->wireless_disp_path_enable = false;
-+ data->wireless_enable = false;
-+
-+ /* Wireless it not supported if VCE is not supported */
-+ if (!init_data->vce_supported)
-+ return true;
-+
-+ if (init_data->miracast_target_required)
-+ data->miracast_connector_enable = true;
-+
-+ /*
-+ * If override is in place for platform support, we will both
-+ * enable wireless display as a feature (i.e. CCC aspect) and
-+ * enable the wireless display path without any further checks.
-+ */
-+ if (init_data->platform_override) {
-+ data->wireless_enable = true;
-+ data->wireless_disp_path_enable = true;
-+ } else {
-+ /*
-+ * Check if SBIOS sets remote display enable, exposed
-+ * through VBIOS. This is only valid for APU, not dGPU
-+ */
-+ dal_bios_parser_get_firmware_info(bp, &info);
-+
-+ if ((REMOTE_DISPLAY_ENABLE ==
-+ info.remote_display_config) &&
-+ init_data->fusion) {
-+ data->wireless_enable = true;
-+ data->wireless_disp_path_enable = true;
-+ }
-+ }
-+
-+ /*
-+ * If remote display path override is enabled, we enable just the
-+ * remote display path. This is mainly used for testing purposes
-+ */
-+ if (init_data->remote_disp_path_override)
-+ data->wireless_disp_path_enable = true;
-+
-+ return true;
-+}
-+
-+uint8_t wireless_get_clocks_num(
-+ struct adapter_service *as)
-+{
-+ if (as->wireless_data.wireless_enable ||
-+ as->wireless_data.wireless_disp_path_enable)
-+ return 1;
-+ else
-+ return 0;
-+}
-+
-+static uint8_t wireless_get_encoders_num(
-+ struct adapter_service *as)
-+{
-+ if (as->wireless_data.wireless_enable ||
-+ as->wireless_data.wireless_disp_path_enable)
-+ return 1;
-+ else
-+ return 0;
-+}
-+
-+uint8_t wireless_get_connectors_num(
-+ struct adapter_service *as)
-+{
-+ uint8_t wireless_connectors_num = 0;
-+
-+ if (as->wireless_data.wireless_enable &&
-+ as->wireless_data.miracast_connector_enable)
-+ wireless_connectors_num++;
-+
-+ if (as->wireless_data.wireless_disp_path_enable)
-+ wireless_connectors_num++;
-+
-+ return wireless_connectors_num;
-+}
-+
-+struct graphics_object_id wireless_get_connector_id(
-+ struct adapter_service *as,
-+ uint8_t index)
-+{
-+ struct graphics_object_id unknown_object_id =
-+ dal_graphics_object_id_init(
-+ 0,
-+ ENUM_ID_UNKNOWN,
-+ OBJECT_TYPE_UNKNOWN);
-+
-+ if (!as->wireless_data.wireless_enable &&
-+ !as->wireless_data.wireless_disp_path_enable)
-+ return unknown_object_id;
-+
-+ else if (!as->wireless_data.miracast_connector_enable)
-+ return dal_graphics_object_id_init(
-+ CONNECTOR_ID_WIRELESS,
-+ ENUM_ID_1,
-+ OBJECT_TYPE_CONNECTOR);
-+
-+ switch (index) {
-+ case 0:
-+ return dal_graphics_object_id_init(
-+ CONNECTOR_ID_WIRELESS,
-+ ENUM_ID_1,
-+ OBJECT_TYPE_CONNECTOR);
-+ break;
-+ case 1:
-+ return dal_graphics_object_id_init(
-+ CONNECTOR_ID_MIRACAST,
-+ ENUM_ID_1,
-+ OBJECT_TYPE_CONNECTOR);
-+ break;
-+ default:
-+ return unknown_object_id;
-+ }
-+}
-+
-+uint8_t wireless_get_srcs_num(
-+ struct adapter_service *as,
-+ struct graphics_object_id id)
-+{
-+ switch (id.type) {
-+ case OBJECT_TYPE_CONNECTOR:
-+ return wireless_get_encoders_num(as);
-+ case OBJECT_TYPE_ENCODER:
-+ return 1;
-+
-+ default:
-+ ASSERT_CRITICAL(false);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+struct graphics_object_id wireless_get_src_obj_id(
-+ struct adapter_service *as,
-+ struct graphics_object_id id,
-+ uint8_t index)
-+{
-+ if (index < wireless_get_srcs_num(as, id)) {
-+ switch (id.type) {
-+ case OBJECT_TYPE_CONNECTOR:
-+ return dal_graphics_object_id_init(
-+ ENCODER_ID_INTERNAL_WIRELESS,
-+ ENUM_ID_1,
-+ OBJECT_TYPE_ENCODER);
-+ break;
-+ case OBJECT_TYPE_ENCODER:
-+ return dal_graphics_object_id_init(
-+ 0,
-+ ENUM_ID_1,
-+ OBJECT_TYPE_GPU);
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ break;
-+ }
-+ }
-+
-+ return dal_graphics_object_id_init(
-+ 0,
-+ ENUM_ID_UNKNOWN,
-+ OBJECT_TYPE_UNKNOWN);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.h b/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.h
-new file mode 100644
-index 0000000..54b140a
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.h
-@@ -0,0 +1,80 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_WIRELESS_DATA_SOURCE_H__
-+#define __DAL_WIRELESS_DATA_SOURCE_H__
-+
-+/* Include */
-+#include "include/grph_object_id.h"
-+
-+/*
-+ * Forward declaration
-+ */
-+struct adapter_service;
-+struct bios_parser;
-+
-+/* Wireless data init structure */
-+struct wireless_init_data {
-+ bool fusion; /* Fusion flag */
-+ bool platform_override; /* Override for platform BIOS option */
-+ bool remote_disp_path_override; /* Override enabling wireless path */
-+ bool vce_supported; /* Existence of VCE block on this DCE */
-+ bool miracast_target_required; /* OS requires Miracast target */
-+};
-+
-+/* Wireless data */
-+struct wireless_data {
-+ bool wireless_enable;
-+ bool wireless_disp_path_enable;
-+ bool miracast_connector_enable;
-+};
-+
-+
-+/*construct wireless data*/
-+bool wireless_data_init(
-+ struct wireless_data *data,
-+ struct bios_parser *bp,
-+ struct wireless_init_data *init_data);
-+
-+uint8_t wireless_get_clocks_num(
-+ struct adapter_service *as);
-+
-+uint8_t wireless_get_connectors_num(
-+ struct adapter_service *as);
-+
-+struct graphics_object_id wireless_get_connector_id(
-+ struct adapter_service *as,
-+ uint8_t connector_index);
-+
-+uint8_t wireless_get_srcs_num(
-+ struct adapter_service *as,
-+ struct graphics_object_id id);
-+
-+struct graphics_object_id wireless_get_src_obj_id(
-+ struct adapter_service *as,
-+ struct graphics_object_id id,
-+ uint8_t index);
-+
-+#endif /* __DAL_WIRELESS_DATA_SOURCE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/asic_capability/Makefile b/drivers/gpu/drm/amd/dal/dc/asic_capability/Makefile
-new file mode 100644
-index 0000000..5e01a86
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/asic_capability/Makefile
-@@ -0,0 +1,23 @@
-+#
-+# Makefile for the 'asic_capability' sub-component of DAL.
-+#
-+
-+ASIC_CAPABILITY = asic_capability.o
-+
-+AMD_DAL_ASIC_CAPABILITY = \
-+ $(addprefix $(AMDDALPATH)/dc/asic_capability/,$(ASIC_CAPABILITY))
-+
-+AMD_DAL_FILES += $(AMD_DAL_ASIC_CAPABILITY)
-+
-+
-+###############################################################################
-+# DCE 11x
-+###############################################################################
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_0
-+ASIC_CAPABILITY_DCE11 = carrizo_asic_capability.o
-+
-+AMD_DAL_ASIC_CAPABILITY_DCE11 = \
-+ $(addprefix $(AMDDALPATH)/dc/asic_capability/,$(ASIC_CAPABILITY_DCE11))
-+
-+AMD_DAL_FILES += $(AMD_DAL_ASIC_CAPABILITY_DCE11)
-+endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/asic_capability/asic_capability.c b/drivers/gpu/drm/amd/dal/dc/asic_capability/asic_capability.c
-new file mode 100644
-index 0000000..a532e2f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/asic_capability/asic_capability.c
-@@ -0,0 +1,178 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "include/logger_interface.h"
-+
-+#include "include/asic_capability_interface.h"
-+#include "include/asic_capability_types.h"
-+#include "include/dal_types.h"
-+#include "include/dal_asic_id.h"
-+
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+#include "carrizo_asic_capability.h"
-+#endif
-+
-+/*
-+ * Initializes asic_capability instance.
-+ */
-+static bool construct(
-+ struct asic_capability *cap,
-+ struct hw_asic_id *init,
-+ struct dc_context *ctx)
-+{
-+ bool asic_supported = false;
-+
-+ cap->ctx = ctx;
-+ dc_service_memset(cap->data, 0, sizeof(cap->data));
-+
-+ /* ASIC data */
-+ cap->data[ASIC_DATA_VRAM_TYPE] = init->vram_type;
-+ cap->data[ASIC_DATA_VRAM_BITWIDTH] = init->vram_width;
-+ cap->data[ASIC_DATA_FEATURE_FLAGS] = init->feature_flags;
-+ cap->runtime_flags = init->runtime_flags;
-+ cap->data[ASIC_DATA_REVISION_ID] = init->hw_internal_rev;
-+ cap->data[ASIC_DATA_MAX_UNDERSCAN_PERCENTAGE] = 10;
-+ cap->data[ASIC_DATA_VIEWPORT_PIXEL_GRANULARITY] = 4;
-+ cap->data[ASIC_DATA_SUPPORTED_HDMI_CONNECTION_NUM] = 1;
-+ cap->data[ASIC_DATA_NUM_OF_VIDEO_PLANES] = 0;
-+ cap->data[ASIC_DATA_DEFAULT_I2C_SPEED_IN_KHZ] = 25;
-+
-+ /* ASIC basic capability */
-+ cap->caps.UNDERSCAN_FOR_HDMI_ONLY = true;
-+ cap->caps.SUPPORT_CEA861E_FINAL = true;
-+ cap->caps.MIRABILIS_SUPPORTED = false;
-+ cap->caps.MIRABILIS_ENABLED_BY_DEFAULT = false;
-+ cap->caps.WIRELESS_LIMIT_TO_720P = false;
-+ cap->caps.WIRELESS_FULL_TIMING_ADJUSTMENT = false;
-+ cap->caps.WIRELESS_TIMING_ADJUSTMENT = true;
-+ cap->caps.WIRELESS_COMPRESSED_AUDIO = false;
-+ cap->caps.VCE_SUPPORTED = false;
-+ cap->caps.HPD_CHECK_FOR_EDID = false;
-+ cap->caps.NO_VCC_OFF_HPD_POLLING = false;
-+ cap->caps.NEED_MC_TUNING = false;
-+ cap->caps.SUPPORT_8BPP = true;
-+
-+ /* ASIC stereo 3D capability */
-+ cap->stereo_3d_caps.SUPPORTED = true;
-+
-+ switch (init->chip_family) {
-+ case FAMILY_CI:
-+ break;
-+
-+ case FAMILY_KV:
-+ if (ASIC_REV_IS_KALINDI(init->hw_internal_rev) ||
-+ ASIC_REV_IS_BHAVANI(init->hw_internal_rev)) {
-+ } else {
-+ }
-+ break;
-+
-+ case FAMILY_CZ:
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ carrizo_asic_capability_create(cap, init);
-+ asic_supported = true;
-+#endif
-+ break;
-+
-+ default:
-+ /* unsupported "chip_family" */
-+ break;
-+ }
-+
-+ if (false == asic_supported) {
-+ dal_logger_write(ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_MASK_ALL,
-+ "%s: ASIC not supported!\n", __func__);
-+ }
-+
-+ return asic_supported;
-+}
-+
-+static void destruct(
-+ struct asic_capability *cap)
-+{
-+ /* nothing to do (yet?) */
-+}
-+
-+/*
-+ * dal_asic_capability_create
-+ *
-+ * Creates asic capability based on DCE version.
-+ */
-+struct asic_capability *dal_asic_capability_create(
-+ struct hw_asic_id *init,
-+ struct dc_context *ctx)
-+{
-+ struct asic_capability *cap;
-+
-+ if (!init) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ cap = dc_service_alloc(ctx, sizeof(struct asic_capability));
-+
-+ if (!cap) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ if (construct(cap, init, ctx))
-+ return cap;
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ dc_service_free(ctx, cap);
-+
-+ return NULL;
-+}
-+
-+/*
-+ * dal_asic_capability_destroy
-+ *
-+ * Destroy allocated memory.
-+ */
-+void dal_asic_capability_destroy(
-+ struct asic_capability **cap)
-+{
-+ if (!cap) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ if (!*cap) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ destruct(*cap);
-+
-+ dc_service_free((*cap)->ctx, *cap);
-+
-+ *cap = NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/asic_capability/carrizo_asic_capability.c b/drivers/gpu/drm/amd/dal/dc/asic_capability/carrizo_asic_capability.c
-new file mode 100644
-index 0000000..f57d3f7
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/asic_capability/carrizo_asic_capability.c
-@@ -0,0 +1,146 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "include/asic_capability_interface.h"
-+#include "include/asic_capability_types.h"
-+
-+#include "carrizo_asic_capability.h"
-+
-+#include "atom.h"
-+#include "dce/dce_11_0_d.h"
-+#include "smu/smu_8_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+#include "dal_asic_id.h"
-+
-+#define ixVCE_HARVEST_FUSE_MACRO__ADDRESS 0xC0014074
-+
-+/*
-+ * carrizo_asic_capability_create
-+ *
-+ * Create and initiate Carrizo capability.
-+ */
-+void carrizo_asic_capability_create(struct asic_capability *cap,
-+ struct hw_asic_id *init)
-+{
-+ uint32_t e_fuse_setting;
-+ /* ASIC data */
-+ cap->data[ASIC_DATA_CONTROLLERS_NUM] = 3;
-+ cap->data[ASIC_DATA_FUNCTIONAL_CONTROLLERS_NUM] = 3;
-+ cap->data[ASIC_DATA_LINEBUFFER_NUM] = 3;
-+ cap->data[ASIC_DATA_PATH_NUM_PER_DPMST_CONNECTOR] = 4;
-+ cap->data[ASIC_DATA_DCE_VERSION] = 0x110; /* DCE 11 */
-+ cap->data[ASIC_DATA_LINEBUFFER_SIZE] = 1712 * 144;
-+ cap->data[ASIC_DATA_DRAM_BANDWIDTH_EFFICIENCY] = 45;
-+ cap->data[ASIC_DATA_CLOCKSOURCES_NUM] = 2;
-+ cap->data[ASIC_DATA_MC_LATENCY] = 5000;
-+ cap->data[ASIC_DATA_STUTTERMODE] = 0x200A;
-+ cap->data[ASIC_DATA_VIEWPORT_PIXEL_GRANULARITY] = 2;
-+ cap->data[ASIC_DATA_MAX_COFUNC_NONDP_DISPLAYS] = 2;
-+ cap->data[ASIC_DATA_MEMORYTYPE_MULTIPLIER] = 2;
-+ cap->data[ASIC_DATA_DEFAULT_I2C_SPEED_IN_KHZ] = 100;
-+ cap->data[ASIC_DATA_NUM_OF_VIDEO_PLANES] = 1;
-+ cap->data[ASIC_DATA_SUPPORTED_HDMI_CONNECTION_NUM] = 3;
-+
-+ /* ASIC basic capability */
-+ cap->caps.IS_FUSION = true;
-+ cap->caps.DP_MST_SUPPORTED = true;
-+ cap->caps.PANEL_SELF_REFRESH_SUPPORTED = true;
-+ cap->caps.MIRABILIS_SUPPORTED = true;
-+ cap->caps.NO_VCC_OFF_HPD_POLLING = true;
-+ cap->caps.VCE_SUPPORTED = true;
-+ cap->caps.HPD_CHECK_FOR_EDID = true;
-+ cap->caps.DFSBYPASS_DYNAMIC_SUPPORT = true;
-+ cap->caps.SUPPORT_8BPP = false;
-+
-+ /* ASIC stereo 3d capability */
-+ cap->stereo_3d_caps.DISPLAY_BASED_ON_WS = true;
-+ cap->stereo_3d_caps.HDMI_FRAME_PACK = true;
-+ cap->stereo_3d_caps.INTERLACE_FRAME_PACK = true;
-+ cap->stereo_3d_caps.DISPLAYPORT_FRAME_PACK = true;
-+ cap->stereo_3d_caps.DISPLAYPORT_FRAME_ALT = true;
-+ cap->stereo_3d_caps.INTERLEAVE = true;
-+
-+ e_fuse_setting = dal_read_index_reg(cap->ctx,CGS_IND_REG__SMC,ixVCE_HARVEST_FUSE_MACRO__ADDRESS);
-+
-+ /* Bits [28:27]*/
-+ switch ((e_fuse_setting >> 27) & 0x3) {
-+ case 0:
-+ /*both VCE engine are working*/
-+ cap->caps.VCE_SUPPORTED = true;
-+ cap->caps.WIRELESS_TIMING_ADJUSTMENT = false;
-+ /*TODO:
-+ cap->caps.wirelessLowVCEPerformance = false;
-+ m_AsicCaps.vceInstance0Enabled = true;
-+ m_AsicCaps.vceInstance1Enabled = true;*/
-+ cap->caps.NEED_MC_TUNING = true;
-+ break;
-+
-+ case 1:
-+ cap->caps.VCE_SUPPORTED = true;
-+ cap->caps.WIRELESS_TIMING_ADJUSTMENT = true;
-+ /*TODO:
-+ m_AsicCaps.wirelessLowVCEPerformance = false;
-+ m_AsicCaps.vceInstance1Enabled = true;*/
-+ cap->caps.NEED_MC_TUNING = true;
-+ break;
-+
-+ case 2:
-+ cap->caps.VCE_SUPPORTED = true;
-+ cap->caps.WIRELESS_TIMING_ADJUSTMENT = true;
-+ /*TODO:
-+ m_AsicCaps.wirelessLowVCEPerformance = false;
-+ m_AsicCaps.vceInstance0Enabled = true;*/
-+ cap->caps.NEED_MC_TUNING = true;
-+ break;
-+
-+ case 3:
-+ /* VCE_DISABLE = 0x3 - both VCE
-+ * instances are in harvesting,
-+ * no VCE supported any more.
-+ */
-+ cap->caps.VCE_SUPPORTED = false;
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ if (ASIC_REV_IS_STONEY(init->hw_internal_rev))
-+ {
-+ /* Stoney is the same DCE11, but only two pipes, three digs.
-+ * and HW added 64bit back for non SG */
-+ cap->data[ASIC_DATA_CONTROLLERS_NUM] = 2;
-+ cap->data[ASIC_DATA_FUNCTIONAL_CONTROLLERS_NUM] = 2;
-+ cap->data[ASIC_DATA_LINEBUFFER_NUM] = 2;
-+ /*3 DP MST per connector, limited by number of pipe and number
-+ * of Dig.*/
-+ cap->data[ASIC_DATA_PATH_NUM_PER_DPMST_CONNECTOR] = 2;
-+
-+ }
-+
-+
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/asic_capability/carrizo_asic_capability.h b/drivers/gpu/drm/amd/dal/dc/asic_capability/carrizo_asic_capability.h
-new file mode 100644
-index 0000000..d1e9b83
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/asic_capability/carrizo_asic_capability.h
-@@ -0,0 +1,36 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_CARRIZO_ASIC_CAPABILITY_H__
-+#define __DAL_CARRIZO_ASIC_CAPABILITY_H__
-+
-+/* Forward declaration */
-+struct asic_capability;
-+
-+/* Create and initialize Carrizo data */
-+void carrizo_asic_capability_create(struct asic_capability *cap,
-+ struct hw_asic_id *init);
-+
-+#endif /* __DAL_CARRIZO_ASIC_CAPABILITY_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/Makefile b/drivers/gpu/drm/amd/dal/dc/audio/Makefile
-new file mode 100644
-index 0000000..0999372
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/Makefile
-@@ -0,0 +1,22 @@
-+#
-+# Makefile for the 'audio' sub-component of DAL.
-+# It provides the control and status of HW adapter resources,
-+# that are global for the ASIC and sharable between pipes.
-+
-+AUDIO = audio_base.o hw_ctx_audio.o
-+
-+AMD_DAL_AUDIO = $(addprefix $(AMDDALPATH)/dc/audio/,$(AUDIO))
-+
-+AMD_DAL_FILES += $(AMD_DAL_AUDIO)
-+
-+
-+###############################################################################
-+# DCE 11x
-+###############################################################################
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_0
-+AUDIO_DCE11 = audio_dce110.o hw_ctx_audio_dce110.o
-+
-+AMD_DAL_AUDIO_DCE11 = $(addprefix $(AMDDALPATH)/dc/audio/dce110/,$(AUDIO_DCE11))
-+
-+AMD_DAL_FILES += $(AMD_DAL_AUDIO_DCE11)
-+endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/audio.h b/drivers/gpu/drm/amd/dal/dc/audio/audio.h
-new file mode 100644
-index 0000000..ad2dc18
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/audio.h
-@@ -0,0 +1,195 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_AUDIO_H__
-+#define __DAL_AUDIO_H__
-+
-+#include "include/audio_interface.h"
-+#include "hw_ctx_audio.h"
-+#include "include/link_service_types.h"
-+
-+/***** only for hook functions *****/
-+/**
-+ *which will be overwritten by derived audio object.
-+ *audio hw context object is independent object
-+ */
-+
-+struct audio;
-+
-+struct audio_funcs {
-+ /*
-+ *get_object_id
-+ *get_object_type
-+ *enumerate_input_signals
-+ *enumerate_output_signals
-+ *is_input_signal_supported
-+ *is_output_signal_supported
-+ *set_object_properties
-+ *get_object_properties
-+ */
-+
-+ void (*destroy)(struct audio **audio);
-+ /*power_up
-+ *power_down
-+ *release_hw_base
-+ */
-+
-+ /* setup audio */
-+ enum audio_result (*setup)(
-+ struct audio *audio,
-+ struct audio_output *output,
-+ struct audio_info *info);
-+
-+ enum audio_result (*enable_output)(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal);
-+
-+ enum audio_result (*disable_output)(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal);
-+
-+ /*enable_azalia_audio_jack_presence
-+ * disable_azalia_audio_jack_presence
-+ */
-+
-+ enum audio_result (*unmute)(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal);
-+
-+ enum audio_result (*mute)(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal);
-+
-+ /* SW initialization that cannot be done in constructor. This will
-+ * be done is audio_power_up but is not in audio_interface. It is only
-+ * called by power_up
-+ */
-+ enum audio_result (*initialize)(
-+ struct audio *audio);
-+
-+ /* enable channel splitting mapping */
-+ void (*enable_channel_splitting_mapping)(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ const struct audio_channel_associate_info *audio_mapping,
-+ bool enable);
-+
-+ /* get current multi channel split. */
-+ enum audio_result (*get_channel_splitting_mapping)(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ struct audio_channel_associate_info *audio_mapping);
-+
-+ /* set payload value for the unsolicited response */
-+ void (*set_unsolicited_response_payload)(
-+ struct audio *audio,
-+ enum audio_payload payload);
-+
-+ /* Update audio wall clock source */
-+ void (*setup_audio_wall_dto)(
-+ struct audio *audio,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_pll_info *pll_info);
-+
-+ /* options and features supported by Audio */
-+ struct audio_feature_support (*get_supported_features)(
-+ struct audio *audio);
-+
-+ /*
-+ *check_audio_bandwidth
-+ *write_reg
-+ *read_reg
-+ *enable_gtc_embedding_with_group
-+ *disable_gtc_embedding
-+ *register_interrupt
-+ *unregister_interrupt
-+ *process_interrupt
-+ *create_hw_ctx
-+ *getHwCtx
-+ *setHwCtx
-+ *handle_interrupt
-+ */
-+};
-+
-+struct audio {
-+ /* hook functions. they will be overwritten by specific ASIC */
-+ const struct audio_funcs *funcs;
-+ /* TODO: static struct audio_funcs funcs;*/
-+
-+ /*external structures - get service from external*/
-+ struct graphics_object_id id;
-+ struct adapter_service *adapter_service;
-+ /* audio HW context */
-+ struct hw_ctx_audio *hw_ctx;
-+ struct dc_context *ctx;
-+ /* audio supports input and output signals */
-+ uint32_t input_signals;
-+ uint32_t output_signals;
-+};
-+
-+/* - functions defined by audio.h will be used by audio component only.
-+ * but audio.c also implements some function defined by dal\include
-+ */
-+
-+/* graphics_object_base implemention
-+ * 1.input_signals and output_signals are moved
-+ * into audio object.
-+ *
-+ * 2.Get the Graphics Object ID
-+ *
-+ * Outside audio:
-+ * use dal_graphics_object_id_get_audio_id
-+ * Within audio:
-+ * use audio->go_base.id
-+ *
-+ * 3. Get the Graphics Object Type
-+ *
-+ * use object_id.type
-+ * not function implemented.
-+ * 4. Common Graphics Object Properties
-+ * use object id ->go_properties.multi_path
-+ * not function implemented.
-+ */
-+
-+bool dal_audio_construct_base(
-+ struct audio *audio,
-+ const struct audio_init_data *init_data);
-+
-+void dal_audio_destruct_base(
-+ struct audio *audio);
-+
-+void dal_audio_release_hw_base(
-+ struct audio *audio);
-+
-+#endif /* __DAL_AUDIO__ */
-+
-+
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/audio_base.c b/drivers/gpu/drm/amd/dal/dc/audio/audio_base.c
-new file mode 100644
-index 0000000..6bac3ed
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/audio_base.c
-@@ -0,0 +1,463 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "include/logger_interface.h"
-+
-+#include "audio.h"
-+#include "hw_ctx_audio.h"
-+
-+#include "dce110/audio_dce110.h"
-+
-+/***** static function : only used within audio.c *****/
-+
-+/* stub for hook functions */
-+static void destroy(
-+ struct audio **audio)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+static enum audio_result setup(
-+ struct audio *audio,
-+ struct audio_output *output,
-+ struct audio_info *info)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+ return AUDIO_RESULT_OK;
-+}
-+
-+static enum audio_result enable_output(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+ return AUDIO_RESULT_OK;
-+}
-+
-+static enum audio_result disable_output(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+ return AUDIO_RESULT_OK;
-+}
-+
-+static enum audio_result unmute(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+ return AUDIO_RESULT_OK;
-+}
-+
-+static enum audio_result mute(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+ return AUDIO_RESULT_OK;
-+}
-+
-+static enum audio_result initialize(
-+ struct audio *audio)
-+{
-+ /*DCE specific, must be implemented in derived. Implemeentaion of
-+ *initialize will create audio hw context. create_hw_ctx
-+ */
-+ BREAK_TO_DEBUGGER();
-+ return AUDIO_RESULT_OK;
-+}
-+
-+static void enable_channel_splitting_mapping(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ const struct audio_channel_associate_info *audio_mapping,
-+ bool enable)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* get current multi channel split. */
-+static enum audio_result get_channel_splitting_mapping(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ struct audio_channel_associate_info *audio_mapping)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/* set payload value for the unsolicited response */
-+static void set_unsolicited_response_payload(
-+ struct audio *audio,
-+ enum audio_payload payload)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* update audio wall clock source */
-+static void setup_audio_wall_dto(
-+ struct audio *audio,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_pll_info *pll_info)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+static struct audio_feature_support get_supported_features(struct audio *audio)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ struct audio_feature_support features;
-+
-+ dc_service_memset(&features, 0, sizeof(features));
-+
-+ features.ENGINE_DIGA = 1;
-+ features.ENGINE_DIGB = 1;
-+
-+ return features;
-+}
-+
-+static const struct audio_funcs audio_funcs = {
-+ .destroy = destroy,
-+ .setup = setup,
-+ .enable_output = enable_output,
-+ .disable_output = disable_output,
-+ .unmute = unmute,
-+ .mute = mute,
-+ .initialize = initialize,
-+ .enable_channel_splitting_mapping =
-+ enable_channel_splitting_mapping,
-+ .get_channel_splitting_mapping =
-+ get_channel_splitting_mapping,
-+ .set_unsolicited_response_payload =
-+ set_unsolicited_response_payload,
-+ .setup_audio_wall_dto = setup_audio_wall_dto,
-+ .get_supported_features = get_supported_features,
-+};
-+
-+/***** SCOPE : declare in audio.h. use within dal-audio. *****/
-+
-+bool dal_audio_construct_base(
-+ struct audio *audio,
-+ const struct audio_init_data *init_data)
-+{
-+ enum signal_type signals = SIGNAL_TYPE_HDMI_TYPE_A;
-+
-+ ASSERT(init_data->as != NULL);
-+
-+ /* base hook functions */
-+ audio->funcs = &audio_funcs;
-+
-+ /*setup pointers to get service from dal service compoenents*/
-+ audio->adapter_service = init_data->as;
-+
-+ audio->ctx = init_data->ctx;
-+
-+ /* save audio endpoint number to identify object creating */
-+ audio->id = init_data->audio_stream_id;
-+
-+ /* Fill supported signals. !!! be aware that android definition is
-+ * already shift to vector.
-+ */
-+ signals |= SIGNAL_TYPE_DISPLAY_PORT;
-+ signals |= SIGNAL_TYPE_DISPLAY_PORT_MST;
-+ signals |= SIGNAL_TYPE_EDP;
-+ signals |= SIGNAL_TYPE_DISPLAY_PORT;
-+ signals |= SIGNAL_TYPE_WIRELESS;
-+
-+ /* Audio supports same set for input and output signals */
-+ audio->input_signals = signals;
-+ audio->output_signals = signals;
-+
-+ return true;
-+}
-+
-+/* except hw_ctx, no other hw need reset. so do nothing */
-+void dal_audio_destruct_base(
-+ struct audio *audio)
-+{
-+}
-+
-+/* Enumerate Graphics Object supported Input/Output Signal Types */
-+uint32_t dal_audio_enumerate_input_signals(
-+ struct audio *audio)
-+{
-+ return audio->input_signals;
-+}
-+
-+uint32_t dal_audio_enumerate_output_signals(
-+ struct audio *audio)
-+{
-+ return audio->output_signals;
-+}
-+
-+/* Check if signal supported by GraphicsObject */
-+bool dal_audio_is_input_signal_supported(
-+ struct audio *audio,
-+ enum signal_type signal)
-+{
-+ return (signal & audio->output_signals) != 0;
-+}
-+
-+bool dal_audio_is_output_signal_supported(
-+ struct audio *audio,
-+ enum signal_type signal)
-+{
-+ return (signal & audio->input_signals) != 0;
-+}
-+
-+/***** SCOPE : declare in dal\include *****/
-+
-+/* audio object creator triage. memory allocate and release will be
-+ * done within dal_audio_create_dcexx
-+ */
-+struct audio *dal_audio_create(
-+ const struct audio_init_data *init_data)
-+{
-+ struct adapter_service *as;
-+
-+ if (init_data->as == NULL)
-+ return NULL;
-+
-+ as = init_data->as;
-+ switch (dal_adapter_service_get_dce_version(as)) {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ case DCE_VERSION_11_0:
-+ return dal_audio_create_dce110(init_data);
-+#endif
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ return NULL;
-+}
-+
-+/* audio object creator triage.
-+ * memory for "struct audio dal_audio_create_dce8x" allocate
-+ * will happens within dal_audio_dce8x. memory allocate is done
-+ * with dal_audio_create_dce8x. memory release is initiated by
-+ * dal_audio_destroy. It will call hook function which will finially
-+ * used destroy() of dal_audio_dce8x. therefore, no memroy allocate
-+ *and release happen physcially at audio base object.
-+ */
-+void dal_audio_destroy(
-+ struct audio **audio)
-+{
-+ if (!audio || !*audio) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ (*audio)->funcs->destroy(audio);
-+
-+ *audio = NULL;
-+}
-+
-+const struct graphics_object_id dal_audio_get_graphics_object_id(
-+ const struct audio *audio)
-+{
-+ return audio->id;
-+}
-+
-+/* enable azalia audio endpoint. This function call hw_ctx directly
-+ *not overwitten at audio level.
-+ */
-+enum audio_result dal_audio_enable_azalia_audio_jack_presence(
-+ struct audio *audio,
-+ enum engine_id engine_id)
-+{
-+ audio->hw_ctx->funcs->enable_azalia_audio(audio->hw_ctx, engine_id);
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/* disable azalia audio endpoint. This function call hw_ctx directly
-+ *not overwitten at audio level.
-+ */
-+enum audio_result dal_audio_disable_azalia_audio_jack_presence(
-+ struct audio *audio,
-+ enum engine_id engine_id)
-+{
-+ audio->hw_ctx->funcs->disable_azalia_audio(audio->hw_ctx, engine_id);
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/* get audio bandwidth information. This function call hw_ctx directly
-+ *not overwitten at audio level.
-+ */
-+void dal_audio_check_audio_bandwidth(
-+ struct audio *audio,
-+ const struct audio_crtc_info *info,
-+ uint32_t channel_count,
-+ enum signal_type signal,
-+ union audio_sample_rates *sample_rates)
-+{
-+ dal_hw_ctx_audio_check_audio_bandwidth(
-+ audio->hw_ctx, info, channel_count, signal, sample_rates);
-+}
-+
-+/* DP Audio register write access. This function call hw_ctx directly
-+ * not overwitten at audio level.
-+ */
-+
-+/*assign GTC group and enable GTC value embedding*/
-+void dal_audio_enable_gtc_embedding_with_group(
-+ struct audio *audio,
-+ uint32_t group_num,
-+ uint32_t audio_latency)
-+{
-+ audio->hw_ctx->funcs->enable_gtc_embedding_with_group(
-+ audio->hw_ctx, group_num, audio_latency);
-+}
-+
-+/* disable GTC value embedding */
-+void dal_audio_disable_gtc_embedding(
-+ struct audio *audio)
-+{
-+ audio->hw_ctx->funcs->disable_gtc_embedding(audio->hw_ctx);
-+}
-+
-+/* perform power up sequence (boot up, resume, recovery) */
-+enum audio_result dal_audio_power_up(
-+ struct audio *audio)
-+{
-+ return audio->funcs->initialize(audio);
-+}
-+
-+/* perform power down (shut down, stand by) */
-+enum audio_result dal_audio_power_down(
-+ struct audio *audio)
-+{
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/* setup audio */
-+enum audio_result dal_audio_setup(
-+ struct audio *audio,
-+ struct audio_output *output,
-+ struct audio_info *info)
-+{
-+ return audio->funcs->setup(audio, output, info);
-+}
-+
-+/* enable audio */
-+enum audio_result dal_audio_enable_output(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ return audio->funcs->enable_output(audio, engine_id, signal);
-+}
-+
-+/* disable audio */
-+enum audio_result dal_audio_disable_output(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ return audio->funcs->disable_output(audio, engine_id, signal);
-+}
-+
-+/* unmute audio */
-+enum audio_result dal_audio_unmute(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ return audio->funcs->unmute(audio, engine_id, signal);
-+}
-+
-+/* mute audio */
-+enum audio_result dal_audio_mute(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ return audio->funcs->mute(audio, engine_id, signal);
-+}
-+
-+/* Enable multi channel split */
-+void dal_audio_enable_channel_splitting_mapping(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ const struct audio_channel_associate_info *audio_mapping,
-+ bool enable)
-+{
-+ audio->funcs->enable_channel_splitting_mapping(
-+ audio, engine_id, signal, audio_mapping, enable);
-+}
-+
-+/* get current multi channel split. */
-+enum audio_result dal_audio_get_channel_splitting_mapping(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ struct audio_channel_associate_info *audio_mapping)
-+{
-+ return audio->funcs->get_channel_splitting_mapping(
-+ audio, engine_id, audio_mapping);
-+}
-+
-+/* set payload value for the unsolicited response */
-+void dal_audio_set_unsolicited_response_payload(
-+ struct audio *audio,
-+ enum audio_payload payload)
-+{
-+ audio->funcs->set_unsolicited_response_payload(audio, payload);
-+}
-+
-+/* update audio wall clock source */
-+void dal_audio_setup_audio_wall_dto(
-+ struct audio *audio,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_pll_info *pll_info)
-+{
-+ audio->funcs->setup_audio_wall_dto(audio, signal, crtc_info, pll_info);
-+}
-+
-+struct audio_feature_support dal_audio_get_supported_features(
-+ struct audio *audio)
-+{
-+ return audio->funcs->get_supported_features(audio);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/dce110/audio_dce110.c b/drivers/gpu/drm/amd/dal/dc/audio/dce110/audio_dce110.c
-new file mode 100644
-index 0000000..f284870
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/dce110/audio_dce110.c
-@@ -0,0 +1,452 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/logger_interface.h"
-+
-+#include "audio_dce110.h"
-+
-+/***** static functions *****/
-+
-+static void destruct(struct audio_dce110 *audio)
-+{
-+ /*release memory allocated for hw_ctx -- allocated is initiated
-+ *by audio_dce110 power_up
-+ *audio->base->hw_ctx = NULL is done within hw-ctx->destroy
-+ */
-+ if (audio->base.hw_ctx)
-+ audio->base.hw_ctx->funcs->destroy(&(audio->base.hw_ctx));
-+
-+ /* reset base_audio_block */
-+ dal_audio_destruct_base(&audio->base);
-+}
-+
-+static void destroy(struct audio **ptr)
-+{
-+ struct audio_dce110 *audio = NULL;
-+
-+ audio = container_of(*ptr, struct audio_dce110, base);
-+
-+ destruct(audio);
-+
-+ /* release memory allocated for audio_dce110*/
-+ dc_service_free((*ptr)->ctx, audio);
-+ *ptr = NULL;
-+}
-+
-+
-+/* The inital call of hook function comes from audio object level.
-+ *The passing object handle "struct audio *audio" point to base object
-+ *already.There is not need to get base object from audio_dce110.
-+ */
-+
-+/**
-+* setup
-+*
-+* @brief
-+* setup Audio HW block, to be called by dal_audio_setup
-+*
-+*/
-+static enum audio_result setup(
-+ struct audio *audio,
-+ struct audio_output *output,
-+ struct audio_info *info)
-+{
-+ switch (output->signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ /*setup HDMI audio engine*/
-+ audio->hw_ctx->funcs->enable_afmt_clock(
-+ audio->hw_ctx,
-+ output->engine_id,
-+ true);
-+ audio->hw_ctx->funcs->setup_hdmi_audio(
-+ audio->hw_ctx, output->engine_id, &output->crtc_info);
-+
-+ audio->hw_ctx->funcs->setup_azalia(
-+ audio->hw_ctx,
-+ output->engine_id,
-+ output->signal,
-+ &output->crtc_info,
-+ &output->pll_info,
-+ info);
-+ break;
-+
-+ case SIGNAL_TYPE_WIRELESS:
-+ /* setup Azalia block for Wireless Display - This
-+ is different than for wired
-+ displays because there is no
-+ DIG to program.*/
-+ /*TODO:
-+ audio->hw_ctx->funcs->setup_azalia_for_vce(
-+ audio->hw_ctx,
-+ audio->signal,
-+ audio->crtc_info,
-+ info);
-+ */
-+ break;
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP:
-+ /* setup DP audio engine will be done at enable output */
-+
-+ /* setup Azalia block*/
-+ audio->hw_ctx->funcs->setup_azalia(
-+ audio->hw_ctx,
-+ output->engine_id,
-+ output->signal,
-+ &output->crtc_info,
-+ &output->pll_info,
-+ info);
-+
-+ break;
-+ default:
-+ return AUDIO_RESULT_ERROR;
-+ }
-+
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/**
-+* enable_output
-+*
-+* @brief
-+* enable Audio HW block, to be called by dal_audio_enable_output
-+*/
-+static enum audio_result enable_output(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ /* enable audio output */
-+ switch (signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ break;
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP: {
-+ /* enable AFMT clock before enable audio*/
-+ audio->hw_ctx->funcs->enable_afmt_clock(
-+ audio->hw_ctx, engine_id, true);
-+ /* setup DP audio engine */
-+ audio->hw_ctx->funcs->setup_dp_audio(
-+ audio->hw_ctx, engine_id);
-+ /* enabl DP audio packets will be done at unblank */
-+ audio->hw_ctx->funcs->enable_dp_audio(
-+ audio->hw_ctx, engine_id);
-+ }
-+ break;
-+ case SIGNAL_TYPE_WIRELESS:
-+ /* route audio to VCE block */
-+ audio->hw_ctx->funcs->setup_vce_audio(audio->hw_ctx);
-+ break;
-+ default:
-+ return AUDIO_RESULT_ERROR;
-+ }
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/**
-+* disable_output
-+*
-+* @brief
-+* disable Audio HW block, to be called by dal_audio_disable_output
-+*
-+*/
-+static enum audio_result disable_output(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ switch (signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ case SIGNAL_TYPE_WIRELESS:
-+ /* disable HDMI audio */
-+ audio->hw_ctx->
-+ funcs->disable_azalia_audio(
-+ audio->hw_ctx, engine_id);
-+ audio->hw_ctx->
-+ funcs->enable_afmt_clock(
-+ audio->hw_ctx, engine_id,
-+ false);
-+
-+ break;
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP: {
-+ /* disable DP audio */
-+ audio->hw_ctx->funcs->disable_dp_audio(
-+ audio->hw_ctx, engine_id);
-+ audio->hw_ctx->funcs->disable_azalia_audio(
-+ audio->hw_ctx, engine_id);
-+ audio->hw_ctx->funcs->enable_afmt_clock(
-+ audio->hw_ctx, engine_id, false);
-+ }
-+ break;
-+ default:
-+ return AUDIO_RESULT_ERROR;
-+ }
-+
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/**
-+* unmute
-+*
-+* @brief
-+* unmute audio, to be called by dal_audio_unmute
-+*
-+*/
-+static enum audio_result unmute(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ switch (signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP:
-+ /* unmute Azalia audio */
-+ audio->hw_ctx->funcs->unmute_azalia_audio(
-+ audio->hw_ctx, engine_id);
-+ break;
-+ case SIGNAL_TYPE_WIRELESS:
-+ /*Do nothing for wireless display*/
-+ break;
-+ default:
-+ return AUDIO_RESULT_ERROR;
-+ }
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/**
-+* mute
-+*
-+* @brief
-+* mute audio, to be called by dal_audio_nmute
-+*
-+*/
-+static enum audio_result mute(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ switch (signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP:
-+ /* mute Azalia audio */
-+ audio->hw_ctx->funcs->mute_azalia_audio(
-+ audio->hw_ctx, engine_id);
-+ break;
-+ case SIGNAL_TYPE_WIRELESS:
-+ /*Do nothing for wireless display*/
-+ break;
-+ default:
-+ return AUDIO_RESULT_ERROR;
-+ }
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/**
-+* initialize
-+*
-+* @brief
-+* Perform SW initialization - create audio hw context. Then do HW
-+* initialization. this function is called at dal_audio_power_up.
-+*
-+*/
-+static enum audio_result initialize(
-+ struct audio *audio)
-+{
-+ uint8_t audio_endpoint_enum_id = 0;
-+
-+ audio_endpoint_enum_id = audio->id.enum_id;
-+
-+ /* HW CTX already create*/
-+ if (audio->hw_ctx != NULL)
-+ return AUDIO_RESULT_OK;
-+
-+ audio->hw_ctx = dal_hw_ctx_audio_dce110_create(
-+ audio->ctx,
-+ audio_endpoint_enum_id);
-+
-+ if (audio->hw_ctx == NULL)
-+ return AUDIO_RESULT_ERROR;
-+
-+ /* override HW default settings */
-+ audio->hw_ctx->funcs->hw_initialize(audio->hw_ctx);
-+
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/* enable multi channel split */
-+static void enable_channel_splitting_mapping(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ const struct audio_channel_associate_info *audio_mapping,
-+ bool enable)
-+{
-+ audio->hw_ctx->funcs->setup_channel_splitting_mapping(
-+ audio->hw_ctx,
-+ engine_id,
-+ signal,
-+ audio_mapping, enable);
-+}
-+
-+/* get current multi channel split. */
-+static enum audio_result get_channel_splitting_mapping(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ struct audio_channel_associate_info *audio_mapping)
-+{
-+ if (audio->hw_ctx->funcs->get_channel_splitting_mapping(
-+ audio->hw_ctx, engine_id, audio_mapping)) {
-+ return AUDIO_RESULT_OK;
-+ } else {
-+ return AUDIO_RESULT_ERROR;
-+ }
-+}
-+
-+/**
-+* set_unsolicited_response_payload
-+*
-+* @brief
-+* Set payload value for the unsolicited response
-+*/
-+static void set_unsolicited_response_payload(
-+ struct audio *audio,
-+ enum audio_payload payload)
-+{
-+ audio->hw_ctx->funcs->set_unsolicited_response_payload(
-+ audio->hw_ctx, payload);
-+}
-+
-+/**
-+* setup_audio_wall_dto
-+*
-+* @brief
-+* Update audio source clock from hardware context.
-+*
-+*/
-+static void setup_audio_wall_dto(
-+ struct audio *audio,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_pll_info *pll_info)
-+{
-+ audio->hw_ctx->funcs->setup_audio_wall_dto(
-+ audio->hw_ctx, signal, crtc_info, pll_info);
-+}
-+
-+/**
-+* get_supported_features
-+*
-+* @brief
-+* options and features supported by Audio
-+* returns supported engines, signals.
-+* features are reported for HW audio/Azalia block rather then Audio object
-+* itself the difference for DCE6.x is that MultiStream Audio is now supported
-+*
-+*/
-+static struct audio_feature_support get_supported_features(struct audio *audio)
-+{
-+ struct audio_feature_support afs = {0};
-+
-+ afs.ENGINE_DIGA = 1;
-+ afs.ENGINE_DIGB = 1;
-+ afs.ENGINE_DIGC = 1;
-+ afs.MULTISTREAM_AUDIO = 1;
-+
-+ return afs;
-+}
-+
-+static const struct audio_funcs funcs = {
-+ .destroy = destroy,
-+ .setup = setup,
-+ .enable_output = enable_output,
-+ .disable_output = disable_output,
-+ .unmute = unmute,
-+ .mute = mute,
-+ .initialize = initialize,
-+ .enable_channel_splitting_mapping =
-+ enable_channel_splitting_mapping,
-+ .get_channel_splitting_mapping =
-+ get_channel_splitting_mapping,
-+ .set_unsolicited_response_payload =
-+ set_unsolicited_response_payload,
-+ .setup_audio_wall_dto = setup_audio_wall_dto,
-+ .get_supported_features = get_supported_features,
-+};
-+
-+static bool construct(
-+ struct audio_dce110 *audio,
-+ const struct audio_init_data *init_data)
-+{
-+ struct audio *base = &audio->base;
-+
-+ /* base audio construct*/
-+ if (!dal_audio_construct_base(base, init_data))
-+ return false;
-+
-+ /*vtable methods*/
-+ base->funcs = &funcs;
-+ return true;
-+}
-+
-+
-+/* --- audio scope functions --- */
-+
-+struct audio *dal_audio_create_dce110(
-+ const struct audio_init_data *init_data)
-+{
-+ /*allocate memory for audio_dce110 */
-+ struct audio_dce110 *audio = dc_service_alloc(init_data->ctx, sizeof(*audio));
-+
-+ if (audio == NULL) {
-+ ASSERT_CRITICAL(audio);
-+ return NULL;
-+ }
-+ /*pointer to base_audio_block of audio_dce110 ==> audio base object */
-+ if (construct(audio, init_data))
-+ return &audio->base;
-+
-+ dal_logger_write(
-+ init_data->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_AUDIO,
-+ "Failed to create audio object for DCE11\n");
-+
-+ /*release memory allocated if fail */
-+ dc_service_free(init_data->ctx, audio);
-+ return NULL;
-+}
-+
-+/* Do not need expose construct_dce110 and destruct_dce110 becuase there is
-+ *derived object after dce110
-+ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/dce110/audio_dce110.h b/drivers/gpu/drm/amd/dal/dc/audio/dce110/audio_dce110.h
-new file mode 100644
-index 0000000..e5ff823
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/dce110/audio_dce110.h
-@@ -0,0 +1,42 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef __DAL_AUDIO_DCE_110_H__
-+#define __DAL_AUDIO_DCE_110_H__
-+
-+#include "audio/audio.h"
-+#include "audio/hw_ctx_audio.h"
-+#include "audio/dce110/hw_ctx_audio_dce110.h"
-+
-+
-+
-+struct audio_dce110 {
-+ struct audio base;
-+ /* dce-specific members are following */
-+ /* none */
-+};
-+
-+struct audio *dal_audio_create_dce110(const struct audio_init_data *init_data);
-+
-+#endif /*__DAL_AUDIO_DCE_110_H__*/
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/dce110/hw_ctx_audio_dce110.c b/drivers/gpu/drm/amd/dal/dc/audio/dce110/hw_ctx_audio_dce110.c
-new file mode 100644
-index 0000000..a13b2ab
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/dce110/hw_ctx_audio_dce110.c
-@@ -0,0 +1,1929 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/logger_interface.h"
-+#include "../hw_ctx_audio.h"
-+#include "hw_ctx_audio_dce110.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#define FROM_BASE(ptr) \
-+ container_of((ptr), struct hw_ctx_audio_dce110, base)
-+
-+#define DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT 0x8000
-+#define DP_AUDIO_DTO_MODULE_WITHOUT_SS 360
-+#define DP_AUDIO_DTO_PHASE_WITHOUT_SS 24
-+
-+#define DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUDIO_FRONT_END 0
-+#define DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC 1
-+#define DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__REGISTER_PROGRAMMABLE 2
-+
-+#define FIRST_AUDIO_STREAM_ID 1
-+
-+#define NOT_IMPLEMENTED() DAL_LOGGER_NOT_IMPL(LOG_MINOR_COMPONENT_AUDIO, \
-+ "Audio:%s()\n", __func__)
-+
-+static const uint32_t engine_offset[] = {
-+ 0,
-+ mmDIG1_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+ mmDIG2_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+ mmDIG3_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL
-+};
-+
-+static void destruct(
-+ struct hw_ctx_audio_dce110 *hw_ctx_dce110)
-+{
-+ dal_audio_destruct_hw_ctx_audio(&hw_ctx_dce110->base);
-+}
-+
-+static void destroy(
-+ struct hw_ctx_audio **ptr)
-+{
-+ struct hw_ctx_audio_dce110 *hw_ctx_dce110;
-+
-+ hw_ctx_dce110 = container_of(
-+ *ptr, struct hw_ctx_audio_dce110, base);
-+
-+ destruct(hw_ctx_dce110);
-+ /* release memory allocated for struct hw_ctx_audio_dce110 */
-+ dc_service_free((*ptr)->ctx, hw_ctx_dce110);
-+
-+ *ptr = NULL;
-+}
-+
-+/* --- helpers --- */
-+static void write_indirect_azalia_reg(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t reg_index,
-+ uint32_t reg_data)
-+{
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+ /* AZALIA_F0_CODEC_ENDPOINT_INDEX endpoint index */
-+ {
-+ addr =
-+ FROM_BASE(hw_ctx)->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_index;
-+
-+ set_reg_field_value(value, reg_index,
-+ AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ AZALIA_ENDPOINT_REG_INDEX);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* AZALIA_F0_CODEC_ENDPOINT_DATA endpoint data */
-+ {
-+ addr =
-+ FROM_BASE(hw_ctx)->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_data;
-+
-+ value = 0;
-+ set_reg_field_value(value, reg_data,
-+ AZALIA_F0_CODEC_ENDPOINT_DATA,
-+ AZALIA_ENDPOINT_REG_DATA);
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ dal_logger_write(
-+ hw_ctx->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_AUDIO,
-+ "AUDIO:write_indirect_azalia_reg: index: %u data: %u\n",
-+ reg_index, reg_data);
-+}
-+
-+static uint32_t read_indirect_azalia_reg(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t reg_index)
-+{
-+ uint32_t ret_val = 0;
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+
-+
-+ /* AZALIA_F0_CODEC_ENDPOINT_INDEX endpoint index */
-+ {
-+ addr =
-+ FROM_BASE(hw_ctx)->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_index;
-+
-+ set_reg_field_value(value, reg_index,
-+ AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ AZALIA_ENDPOINT_REG_INDEX);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* AZALIA_F0_CODEC_ENDPOINT_DATA endpoint data */
-+ {
-+ addr =
-+ FROM_BASE(hw_ctx)->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_data;
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ ret_val = value;
-+ }
-+
-+ dal_logger_write(
-+ hw_ctx->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_AUDIO,
-+ "AUDIO:read_indirect_azalia_reg: index: %u data: %u\n",
-+ reg_index, ret_val);
-+
-+ return ret_val;
-+}
-+
-+/* expose/not expose HBR capability to Audio driver */
-+static void set_high_bit_rate_capable(
-+ const struct hw_ctx_audio *hw_ctx,
-+ bool capable)
-+{
-+ uint32_t value = 0;
-+
-+ /* set high bit rate audio capable*/
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR);
-+
-+ set_reg_field_value(value, capable,
-+ AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR,
-+ HBR_CAPABLE);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR,
-+ value);
-+}
-+
-+/* set HBR channnel count *
-+static void set_hbr_channel_count(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t hbr_channel_count)
-+{
-+ uint32_t value = 0;
-+
-+ if (hbr_channel_count > 7)
-+ return;
-+
-+ value = dal_read_reg(hw_ctx->ctx,
-+ mmAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL);
-+
-+ set_reg_field_value(value, hbr_channel_count,
-+ AZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL,
-+ HBR_CHANNEL_COUNT);
-+
-+ dal_write_reg(hw_ctx->ctx,
-+ mmAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL, value);
-+
-+}
-+
-+*set compressed audio channel count *
-+static void set_compressed_audio_channel_count(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t compressed_audio_ch_count)
-+{
-+ uint32_t value = 0;
-+ if (compressed_audio_ch_count > 7)
-+ return;
-+
-+ value = dal_read_reg(hw_ctx->ctx,
-+ mmAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL);
-+
-+ set_reg_field_value(value, compressed_audio_ch_count,
-+ AZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL,
-+ COMPRESSED_CHANNEL_COUNT);
-+
-+ dal_write_reg(hw_ctx->ctx,
-+ mmAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL,
-+ value);
-+
-+}
-+*/
-+/* set video latency in in ms/2+1 */
-+static void set_video_latency(
-+ const struct hw_ctx_audio *hw_ctx,
-+ int latency_in_ms)
-+{
-+ uint32_t value = 0;
-+
-+ if ((latency_in_ms < 0) || (latency_in_ms > 255))
-+ return;
-+
-+
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);
-+
-+ set_reg_field_value(value, latency_in_ms,
-+ AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
-+ VIDEO_LIPSYNC);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
-+ value);
-+
-+}
-+
-+/* set audio latency in in ms/2+1 */
-+static void set_audio_latency(
-+ const struct hw_ctx_audio *hw_ctx,
-+ int latency_in_ms)
-+{
-+ uint32_t value = 0;
-+
-+ if (latency_in_ms < 0)
-+ latency_in_ms = 0;
-+
-+ if (latency_in_ms > 255)
-+ latency_in_ms = 255;
-+
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);
-+
-+ set_reg_field_value(value, latency_in_ms,
-+ AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
-+ AUDIO_LIPSYNC);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
-+ value);
-+
-+}
-+
-+/* enable HW/SW Sync */
-+/*static void enable_hw_sw_sync(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ union AZALIA_CYCLIC_BUFFER_SYNC value;
-+
-+ value = dal_read_reg(mmAZALIA_CYCLIC_BUFFER_SYNC);
-+ value.bits.CYCLIC_BUFFER_SYNC_ENABLE = 1;
-+ dal_write_reg(mmAZALIA_CYCLIC_BUFFER_SYNC, value);
-+}*/
-+
-+/* disable HW/SW Sync */
-+/*static void disable_hw_sw_sync(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ union AZALIA_CYCLIC_BUFFER_SYNC value;
-+
-+ value = dal_read_reg(
-+ mmAZALIA_CYCLIC_BUFFER_SYNC);
-+ value.bits.CYCLIC_BUFFER_SYNC_ENABLE = 0;
-+ dal_write_reg(
-+ mmAZALIA_CYCLIC_BUFFER_SYNC, value);
-+}*/
-+
-+/* update hardware with software's current position in cyclic buffer */
-+/*static void update_sw_write_ptr(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t offset)
-+{
-+ union AZALIA_APPLICATION_POSITION_IN_CYCLIC_BUFFER value;
-+
-+ value = dal_read_reg(
-+ mmAZALIA_APPLICATION_POSITION_IN_CYCLIC_BUFFER);
-+ value.bits.APPLICATION_POSITION_IN_CYCLIC_BUFFER = offset;
-+ dal_write_reg(
-+ mmAZALIA_APPLICATION_POSITION_IN_CYCLIC_BUFFER,
-+ value);
-+}*/
-+
-+/* update Audio/Video association */
-+/*static void update_av_association(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ uint32_t displayId)
-+{
-+
-+}*/
-+
-+/* --- hook functions --- */
-+static bool get_azalia_clock_info_hdmi(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t crtc_pixel_clock_in_khz,
-+ uint32_t actual_pixel_clock_in_khz,
-+ struct azalia_clock_info *azalia_clock_info);
-+
-+static bool get_azalia_clock_info_dp(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t requested_pixel_clock_in_khz,
-+ const struct audio_pll_info *pll_info,
-+ struct azalia_clock_info *azalia_clock_info);
-+
-+static void setup_audio_wall_dto(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_pll_info *pll_info)
-+{
-+ struct azalia_clock_info clock_info = { 0 };
-+
-+ uint32_t value = dal_read_reg(hw_ctx->ctx, mmDCCG_AUDIO_DTO_SOURCE);
-+
-+ /* TODO: GraphicsObject\inc\GraphicsObjectDefs.hpp(131):
-+ *inline bool isHdmiSignal(SignalType signal)
-+ *if (Signals::isHdmiSignal(signal))
-+ */
-+ if (dc_is_hdmi_signal(signal)) {
-+ /*DTO0 Programming goal:
-+ -generate 24MHz, 128*Fs from 24MHz
-+ -use DTO0 when an active HDMI port is connected
-+ (optionally a DP is connected) */
-+
-+ /* calculate DTO settings */
-+ get_azalia_clock_info_hdmi(
-+ hw_ctx,
-+ crtc_info->requested_pixel_clock,
-+ crtc_info->calculated_pixel_clock,
-+ &clock_info);
-+
-+ /* On TN/SI, Program DTO source select and DTO select before
-+ programming DTO modulo and DTO phase. These bits must be
-+ programmed first, otherwise there will be no HDMI audio at boot
-+ up. This is a HW sequence change (different from old ASICs).
-+ Caution when changing this programming sequence.
-+
-+ HDMI enabled, using DTO0
-+ program master CRTC for DTO0 */
-+ {
-+ set_reg_field_value(value,
-+ pll_info->dto_source - DTO_SOURCE_ID0,
-+ DCCG_AUDIO_DTO_SOURCE,
-+ DCCG_AUDIO_DTO0_SOURCE_SEL);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ DCCG_AUDIO_DTO_SOURCE,
-+ DCCG_AUDIO_DTO_SEL);
-+
-+ dal_write_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO_SOURCE, value);
-+ }
-+
-+ /* module */
-+ {
-+ value = dal_read_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO0_MODULE);
-+ set_reg_field_value(value,
-+ clock_info.audio_dto_module,
-+ DCCG_AUDIO_DTO0_MODULE,
-+ DCCG_AUDIO_DTO0_MODULE);
-+ dal_write_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO0_MODULE, value);
-+ }
-+
-+ /* phase */
-+ {
-+ value = 0;
-+
-+ value = dal_read_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO0_PHASE);
-+ set_reg_field_value(value,
-+ clock_info.audio_dto_phase,
-+ DCCG_AUDIO_DTO0_PHASE,
-+ DCCG_AUDIO_DTO0_PHASE);
-+
-+ dal_write_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO0_PHASE, value);
-+ }
-+
-+ } else {
-+ /*DTO1 Programming goal:
-+ -generate 24MHz, 512*Fs, 128*Fs from 24MHz
-+ -default is to used DTO1, and switch to DTO0 when an audio
-+ master HDMI port is connected
-+ -use as default for DP
-+
-+ calculate DTO settings */
-+ get_azalia_clock_info_dp(
-+ hw_ctx,
-+ crtc_info->requested_pixel_clock,
-+ pll_info,
-+ &clock_info);
-+
-+ /* Program DTO select before programming DTO modulo and DTO
-+ phase. default to use DTO1 */
-+
-+ {
-+ set_reg_field_value(value, 1,
-+ DCCG_AUDIO_DTO_SOURCE,
-+ DCCG_AUDIO_DTO_SEL);
-+ /*dal_write_reg(mmDCCG_AUDIO_DTO_SOURCE, value)*/
-+
-+ /* Select 512fs for DP TODO: web register definition
-+ does not match register header file
-+ set_reg_field_value(value, 1,
-+ DCCG_AUDIO_DTO_SOURCE,
-+ DCCG_AUDIO_DTO2_USE_512FBR_DTO);
-+ */
-+
-+ dal_write_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO_SOURCE, value);
-+ }
-+
-+ /* module */
-+ {
-+ value = 0;
-+
-+ value = dal_read_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO1_MODULE);
-+
-+ set_reg_field_value(value,
-+ clock_info.audio_dto_module,
-+ DCCG_AUDIO_DTO1_MODULE,
-+ DCCG_AUDIO_DTO1_MODULE);
-+
-+ dal_write_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO1_MODULE, value);
-+ }
-+
-+ /* phase */
-+ {
-+ value = 0;
-+
-+ value = dal_read_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO1_PHASE);
-+
-+ set_reg_field_value(value,
-+ clock_info.audio_dto_phase,
-+ DCCG_AUDIO_DTO1_PHASE,
-+ DCCG_AUDIO_DTO1_PHASE);
-+
-+ dal_write_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO1_PHASE, value);
-+ }
-+
-+ /* DAL2 code separate DCCG_AUDIO_DTO_SEL and
-+ DCCG_AUDIO_DTO2_USE_512FBR_DTO programming into two different
-+ location. merge together should not hurt */
-+ /*value.bits.DCCG_AUDIO_DTO2_USE_512FBR_DTO = 1;
-+ dal_write_reg(mmDCCG_AUDIO_DTO_SOURCE, value);*/
-+ }
-+}
-+
-+/* setup HDMI audio */
-+static void setup_hdmi_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ const struct audio_crtc_info *crtc_info)
-+{
-+ struct audio_clock_info audio_clock_info = {0};
-+ uint32_t max_packets_per_line;
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+
-+ /* For now still do calculation, although this field is ignored when
-+ above HDMI_PACKET_GEN_VERSION set to 1 */
-+ max_packets_per_line =
-+ dal_audio_hw_ctx_calc_max_audio_packets_per_line(
-+ hw_ctx,
-+ crtc_info);
-+
-+ /* HDMI_AUDIO_PACKET_CONTROL */
-+ {
-+ addr =
-+ mmHDMI_AUDIO_PACKET_CONTROL + engine_offset[engine_id];
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, max_packets_per_line,
-+ HDMI_AUDIO_PACKET_CONTROL,
-+ HDMI_AUDIO_PACKETS_PER_LINE);
-+ /* still apply RS600's default setting which is 1. */
-+ set_reg_field_value(value, 1,
-+ HDMI_AUDIO_PACKET_CONTROL,
-+ HDMI_AUDIO_DELAY_EN);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* AFMT_AUDIO_PACKET_CONTROL */
-+ {
-+ addr = mmAFMT_AUDIO_PACKET_CONTROL + engine_offset[engine_id];
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, 1,
-+ AFMT_AUDIO_PACKET_CONTROL,
-+ AFMT_60958_CS_UPDATE);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* AFMT_AUDIO_PACKET_CONTROL2 */
-+ {
-+ addr = mmAFMT_AUDIO_PACKET_CONTROL2 + engine_offset[engine_id];
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, 0,
-+ AFMT_AUDIO_PACKET_CONTROL2,
-+ AFMT_AUDIO_LAYOUT_OVRD);
-+
-+ /*Register field changed.*/
-+ set_reg_field_value(value, 0,
-+ AFMT_AUDIO_PACKET_CONTROL2,
-+ AFMT_60958_OSF_OVRD);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* HDMI_ACR_PACKET_CONTROL */
-+ {
-+ addr = mmHDMI_ACR_PACKET_CONTROL + engine_offset[engine_id];
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, 1,
-+ HDMI_ACR_PACKET_CONTROL,
-+ HDMI_ACR_AUTO_SEND);
-+
-+ /* Set HDMI_ACR_SOURCE to 0, to use hardwre
-+ * computed CTS values.*/
-+ set_reg_field_value(value, 0,
-+ HDMI_ACR_PACKET_CONTROL,
-+ HDMI_ACR_SOURCE);
-+
-+ /* For now clear HDMI_ACR_AUDIO_PRIORITY =>ACR packet has
-+ higher priority over Audio Sample */
-+ set_reg_field_value(value, 0,
-+ HDMI_ACR_PACKET_CONTROL,
-+ HDMI_ACR_AUDIO_PRIORITY);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* Program audio clock sample/regeneration parameters */
-+ if (dal_audio_hw_ctx_get_audio_clock_info(
-+ hw_ctx,
-+ crtc_info->color_depth,
-+ crtc_info->requested_pixel_clock,
-+ crtc_info->calculated_pixel_clock,
-+ &audio_clock_info)) {
-+
-+ /* HDMI_ACR_32_0__HDMI_ACR_CTS_32_MASK */
-+ {
-+ addr = mmHDMI_ACR_32_0 + engine_offset[engine_id];
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, audio_clock_info.cts_32khz,
-+ HDMI_ACR_32_0,
-+ HDMI_ACR_CTS_32);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* HDMI_ACR_32_1__HDMI_ACR_N_32_MASK */
-+ {
-+ addr = mmHDMI_ACR_32_1 + engine_offset[engine_id];
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, audio_clock_info.n_32khz,
-+ HDMI_ACR_32_1,
-+ HDMI_ACR_N_32);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* HDMI_ACR_44_0__HDMI_ACR_CTS_44_MASK */
-+ {
-+ addr = mmHDMI_ACR_44_0 + engine_offset[engine_id];
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, audio_clock_info.cts_44khz,
-+ HDMI_ACR_44_0,
-+ HDMI_ACR_CTS_44);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* HDMI_ACR_44_1__HDMI_ACR_N_44_MASK */
-+ {
-+ addr = mmHDMI_ACR_44_1 + engine_offset[engine_id];
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, audio_clock_info.n_44khz,
-+ HDMI_ACR_44_1,
-+ HDMI_ACR_N_44);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* HDMI_ACR_48_0__HDMI_ACR_CTS_48_MASK */
-+ {
-+ addr = mmHDMI_ACR_48_0 + engine_offset[engine_id];
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, audio_clock_info.cts_48khz,
-+ HDMI_ACR_48_0,
-+ HDMI_ACR_CTS_48);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* HDMI_ACR_48_1__HDMI_ACR_N_48_MASK */
-+ {
-+ addr = mmHDMI_ACR_48_1 + engine_offset[engine_id];
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, audio_clock_info.n_48khz,
-+ HDMI_ACR_48_1,
-+ HDMI_ACR_N_48);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* Video driver cannot know in advance which sample rate will
-+ be used by HD Audio driver
-+ HDMI_ACR_PACKET_CONTROL__HDMI_ACR_N_MULTIPLE field is
-+ programmed below in interruppt callback */
-+ } /* if */
-+
-+ /* AFMT_60958_0__AFMT_60958_CS_CHANNEL_NUMBER_L_MASK &
-+ AFMT_60958_0__AFMT_60958_CS_CLOCK_ACCURACY_MASK */
-+ {
-+ addr = mmAFMT_60958_0 + engine_offset[engine_id];
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, 1,
-+ AFMT_60958_0,
-+ AFMT_60958_CS_CHANNEL_NUMBER_L);
-+
-+ /*HW default */
-+ set_reg_field_value(value, 0,
-+ AFMT_60958_0,
-+ AFMT_60958_CS_CLOCK_ACCURACY);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* AFMT_60958_1 AFMT_60958_CS_CHALNNEL_NUMBER_R */
-+ {
-+ addr = mmAFMT_60958_1 + engine_offset[engine_id];
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, 2,
-+ AFMT_60958_1,
-+ AFMT_60958_CS_CHANNEL_NUMBER_R);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /*AFMT_60958_2 now keep this settings until
-+ * Programming guide comes out*/
-+ {
-+ addr = mmAFMT_60958_2 + engine_offset[engine_id];
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, 3,
-+ AFMT_60958_2,
-+ AFMT_60958_CS_CHANNEL_NUMBER_2);
-+
-+ set_reg_field_value(value, 4,
-+ AFMT_60958_2,
-+ AFMT_60958_CS_CHANNEL_NUMBER_3);
-+
-+ set_reg_field_value(value, 5,
-+ AFMT_60958_2,
-+ AFMT_60958_CS_CHANNEL_NUMBER_4);
-+
-+ set_reg_field_value(value, 6,
-+ AFMT_60958_2,
-+ AFMT_60958_CS_CHANNEL_NUMBER_5);
-+
-+ set_reg_field_value(value, 7,
-+ AFMT_60958_2,
-+ AFMT_60958_CS_CHANNEL_NUMBER_6);
-+
-+ set_reg_field_value(value, 8,
-+ AFMT_60958_2,
-+ AFMT_60958_CS_CHANNEL_NUMBER_7);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+}
-+
-+ /* setup DP audio */
-+static void setup_dp_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ /* --- DP Audio packet configurations --- */
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+
-+ /* ATP Configuration */
-+ {
-+ addr = mmDP_SEC_AUD_N + engine_offset[engine_id];
-+
-+ set_reg_field_value(value,
-+ DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT,
-+ DP_SEC_AUD_N,
-+ DP_SEC_AUD_N);
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* Async/auto-calc timestamp mode */
-+ {
-+ addr = mmDP_SEC_TIMESTAMP +
-+ engine_offset[engine_id];
-+
-+ value = 0;
-+
-+ set_reg_field_value(value,
-+ DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC,
-+ DP_SEC_TIMESTAMP,
-+ DP_SEC_TIMESTAMP_MODE);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* --- The following are the registers
-+ * copied from the SetupHDMI --- */
-+
-+
-+ /* AFMT_AUDIO_PACKET_CONTROL */
-+ {
-+ addr = mmAFMT_AUDIO_PACKET_CONTROL +
-+ engine_offset[engine_id];
-+
-+ value = 0;
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value,
-+ 1,
-+ AFMT_AUDIO_PACKET_CONTROL,
-+ AFMT_60958_CS_UPDATE);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* AFMT_AUDIO_PACKET_CONTROL2 */
-+ {
-+ addr =
-+ mmAFMT_AUDIO_PACKET_CONTROL2 + engine_offset[engine_id];
-+
-+ value = 0;
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value,
-+ 0,
-+ AFMT_AUDIO_PACKET_CONTROL2,
-+ AFMT_AUDIO_LAYOUT_OVRD);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ AFMT_AUDIO_PACKET_CONTROL2,
-+ AFMT_60958_OSF_OVRD);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* AFMT_INFOFRAME_CONTROL0 */
-+ {
-+ addr =
-+ mmAFMT_INFOFRAME_CONTROL0 + engine_offset[engine_id];
-+
-+ value = 0;
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value,
-+ 1,
-+ AFMT_INFOFRAME_CONTROL0,
-+ AFMT_AUDIO_INFO_UPDATE);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* AFMT_60958_0__AFMT_60958_CS_CLOCK_ACCURACY_MASK */
-+ {
-+ addr = mmAFMT_60958_0 + engine_offset[engine_id];
-+
-+ value = 0;
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value,
-+ 0,
-+ AFMT_60958_0,
-+ AFMT_60958_CS_CLOCK_ACCURACY);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+}
-+
-+ /* setup VCE audio */
-+static void setup_vce_audio(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ struct dc_context *ctx = hw_ctx->ctx;
-+
-+ NOT_IMPLEMENTED();
-+
-+ /*TODO:
-+ const uint32_t addr = mmDOUT_DCE_VCE_CONTROL;
-+ uint32_t value = 0;
-+
-+ value = dal_read_reg(hw_ctx->ctx,
-+ addr);
-+
-+ set_reg_field_value(value,
-+ FROM_BASE(hw_ctx)->azalia_stream_id - 1,
-+ DOUT_DCE_VCE_CONTROL,
-+ DC_VCE_AUDIO_STREAM_SELECT);
-+
-+ dal_write_reg(hw_ctx->ctx,
-+ addr, value);*/
-+}
-+
-+static void enable_afmt_clock(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ bool enable_flag)
-+{
-+ uint32_t engine_offs = engine_offset[engine_id];
-+ uint32_t value;
-+ uint32_t count = 0;
-+ uint32_t enable = enable_flag ? 1:0;
-+
-+ /* Enable Audio packets*/
-+ value = dal_read_reg(hw_ctx->ctx, mmAFMT_CNTL + engine_offs);
-+
-+ /*enable AFMT clock*/
-+ set_reg_field_value(value, enable,
-+ AFMT_CNTL, AFMT_AUDIO_CLOCK_EN);
-+ dal_write_reg(hw_ctx->ctx, mmAFMT_CNTL + engine_offs, value);
-+
-+ /*wait for AFMT clock to turn on,
-+ * the expectation is that this
-+ * should complete in 1-2 reads)
-+ */
-+ do {
-+ /* Wait for 1us between subsequent register reads.*/
-+ dc_service_delay_in_microseconds(hw_ctx->ctx, 1);
-+ value = dal_read_reg(hw_ctx->ctx,
-+ mmAFMT_CNTL + engine_offs);
-+ } while (get_reg_field_value(value,
-+ AFMT_CNTL, AFMT_AUDIO_CLOCK_ON) !=
-+ enable && count++ < 10);
-+}
-+
-+/* enable Azalia audio */
-+static void enable_azalia_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ uint32_t value;
-+
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
-+
-+ if (get_reg_field_value(value,
-+ AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
-+ AUDIO_ENABLED) != 1)
-+ set_reg_field_value(value, 1,
-+ AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
-+ AUDIO_ENABLED);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
-+ value);
-+}
-+
-+/* disable Azalia audio */
-+static void disable_azalia_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ uint32_t value;
-+
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
-+
-+ set_reg_field_value(value, 0,
-+ AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
-+ AUDIO_ENABLED);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
-+ value);
-+}
-+
-+/* enable DP audio */
-+static void enable_dp_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ const uint32_t addr = mmDP_SEC_CNTL + engine_offset[engine_id];
-+
-+ uint32_t value;
-+
-+ /* Enable Audio packets */
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, 1,
-+ DP_SEC_CNTL,
-+ DP_SEC_ASP_ENABLE);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+
-+ /* Program the ATP and AIP next */
-+ set_reg_field_value(value, 1,
-+ DP_SEC_CNTL,
-+ DP_SEC_ATP_ENABLE);
-+
-+ set_reg_field_value(value, 1,
-+ DP_SEC_CNTL,
-+ DP_SEC_AIP_ENABLE);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+
-+ /* Program STREAM_ENABLE after all the other enables. */
-+ set_reg_field_value(value, 1,
-+ DP_SEC_CNTL,
-+ DP_SEC_STREAM_ENABLE);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+}
-+
-+/* disable DP audio */
-+static void disable_dp_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ const uint32_t addr = mmDP_SEC_CNTL + engine_offset[engine_id];
-+
-+ uint32_t value;
-+
-+ /* Disable Audio packets */
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, 0,
-+ DP_SEC_CNTL,
-+ DP_SEC_ASP_ENABLE);
-+
-+ set_reg_field_value(value, 0,
-+ DP_SEC_CNTL,
-+ DP_SEC_ATP_ENABLE);
-+
-+ set_reg_field_value(value, 0,
-+ DP_SEC_CNTL,
-+ DP_SEC_AIP_ENABLE);
-+
-+ set_reg_field_value(value, 0,
-+ DP_SEC_CNTL,
-+ DP_SEC_ACM_ENABLE);
-+
-+ set_reg_field_value(value, 0,
-+ DP_SEC_CNTL,
-+ DP_SEC_STREAM_ENABLE);
-+
-+ /* This register shared with encoder info frame. Therefore we need to
-+ keep master enabled if at least on of the fields is not 0 */
-+ if (value != 0)
-+ set_reg_field_value(value, 1,
-+ DP_SEC_CNTL,
-+ DP_SEC_STREAM_ENABLE);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+}
-+
-+static void configure_azalia(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_info *audio_info)
-+{
-+ uint32_t speakers = audio_info->flags.info.ALLSPEAKERS;
-+ uint32_t value;
-+ uint32_t field = 0;
-+ enum audio_format_code audio_format_code;
-+ uint32_t format_index;
-+ uint32_t index;
-+ bool is_ac3_supported = false;
-+ bool is_audio_format_supported = false;
-+ union audio_sample_rates sample_rate;
-+ uint32_t strlen = 0;
-+
-+ /* Speaker Allocation */
-+ /*
-+ uint32_t value;
-+ uint32_t field = 0;*/
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
-+
-+ set_reg_field_value(value,
-+ speakers,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ SPEAKER_ALLOCATION);
-+
-+ /* LFE_PLAYBACK_LEVEL = LFEPBL
-+ * LFEPBL = 0 : Unknown or refer to other information
-+ * LFEPBL = 1 : 0dB playback
-+ * LFEPBL = 2 : +10dB playback
-+ * LFE_BL = 3 : Reserved
-+ */
-+ set_reg_field_value(value,
-+ 0,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ LFE_PLAYBACK_LEVEL);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ HDMI_CONNECTION);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ DP_CONNECTION);
-+
-+ field = get_reg_field_value(value,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ EXTRA_CONNECTION_INFO);
-+
-+ field &= ~0x1;
-+
-+ set_reg_field_value(value,
-+ field,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ EXTRA_CONNECTION_INFO);
-+
-+ /* set audio for output signal */
-+ switch (signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ set_reg_field_value(value,
-+ 1,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ HDMI_CONNECTION);
-+
-+ break;
-+ case SIGNAL_TYPE_WIRELESS: {
-+ /*LSB used for "is wireless" flag */
-+ field = 0;
-+ field = get_reg_field_value(value,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ EXTRA_CONNECTION_INFO);
-+ field |= 0x1;
-+ set_reg_field_value(value,
-+ field,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ EXTRA_CONNECTION_INFO);
-+
-+ set_reg_field_value(value,
-+ 1,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ HDMI_CONNECTION);
-+
-+ }
-+ break;
-+ case SIGNAL_TYPE_EDP:
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ set_reg_field_value(value,
-+ 1,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ DP_CONNECTION);
-+
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ value);
-+
-+ /* Wireless Display identification */
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION);
-+
-+ set_reg_field_value(value,
-+ signal == SIGNAL_TYPE_WIRELESS ? 1 : 0,
-+ AZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION,
-+ WIRELESS_DISPLAY_IDENTIFICATION);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION,
-+ value);
-+
-+ /* Audio Descriptors */
-+ /* pass through all formats */
-+ for (format_index = 0; format_index < AUDIO_FORMAT_CODE_COUNT;
-+ format_index++) {
-+ audio_format_code =
-+ (AUDIO_FORMAT_CODE_FIRST + format_index);
-+
-+ /* those are unsupported, skip programming */
-+ if (audio_format_code == AUDIO_FORMAT_CODE_1BITAUDIO ||
-+ audio_format_code == AUDIO_FORMAT_CODE_DST)
-+ continue;
-+
-+ value = 0;
-+
-+ /* check if supported */
-+ is_audio_format_supported =
-+ dal_audio_hw_ctx_is_audio_format_supported(
-+ hw_ctx,
-+ audio_info,
-+ audio_format_code, &index);
-+
-+ if (is_audio_format_supported) {
-+ const struct audio_mode *audio_mode =
-+ &audio_info->modes[index];
-+ union audio_sample_rates sample_rates =
-+ audio_mode->sample_rates;
-+ uint8_t byte2 = audio_mode->max_bit_rate;
-+
-+ /* adjust specific properties */
-+ switch (audio_format_code) {
-+ case AUDIO_FORMAT_CODE_LINEARPCM: {
-+ dal_hw_ctx_audio_check_audio_bandwidth(
-+ hw_ctx,
-+ crtc_info,
-+ audio_mode->channel_count,
-+ signal,
-+ &sample_rates);
-+
-+ byte2 = audio_mode->sample_size;
-+
-+ set_reg_field_value(value,
-+ sample_rates.all,
-+ AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
-+ SUPPORTED_FREQUENCIES_STEREO);
-+
-+ }
-+ break;
-+ case AUDIO_FORMAT_CODE_AC3:
-+ is_ac3_supported = true;
-+ break;
-+ case AUDIO_FORMAT_CODE_DOLBYDIGITALPLUS:
-+ case AUDIO_FORMAT_CODE_DTS_HD:
-+ case AUDIO_FORMAT_CODE_MAT_MLP:
-+ case AUDIO_FORMAT_CODE_DST:
-+ case AUDIO_FORMAT_CODE_WMAPRO:
-+ byte2 = audio_mode->vendor_specific;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ /* fill audio format data */
-+ set_reg_field_value(value,
-+ audio_mode->channel_count - 1,
-+ AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
-+ MAX_CHANNELS);
-+
-+ set_reg_field_value(value,
-+ sample_rates.all,
-+ AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
-+ SUPPORTED_FREQUENCIES);
-+
-+ set_reg_field_value(value,
-+ byte2,
-+ AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
-+ DESCRIPTOR_BYTE_2);
-+
-+ } /* if */
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 +
-+ format_index,
-+ value);
-+ } /* for */
-+
-+ if (is_ac3_supported)
-+ dal_write_reg(hw_ctx->ctx,
-+ mmAZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS,
-+ 0x05);
-+
-+ /* check for 192khz/8-Ch support for HBR requirements */
-+ sample_rate.all = 0;
-+ sample_rate.rate.RATE_192 = 1;
-+ dal_hw_ctx_audio_check_audio_bandwidth(
-+ hw_ctx,
-+ crtc_info,
-+ 8,
-+ signal,
-+ &sample_rate);
-+
-+ set_high_bit_rate_capable(hw_ctx, sample_rate.rate.RATE_192);
-+
-+ /* Audio and Video Lipsync */
-+ set_video_latency(hw_ctx, audio_info->video_latency);
-+ set_audio_latency(hw_ctx, audio_info->audio_latency);
-+
-+ value = 0;
-+ set_reg_field_value(value, audio_info->manufacture_id,
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
-+ MANUFACTURER_ID);
-+
-+ set_reg_field_value(value, audio_info->product_id,
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
-+ PRODUCT_ID);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
-+ value);
-+
-+
-+ value = 0;
-+
-+ /*get display name string length */
-+ while (audio_info->display_name[strlen++] != '\0') {
-+ if (strlen >=
-+ MAX_HW_AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS)
-+ break;
-+ }
-+ set_reg_field_value(value, strlen,
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,
-+ SINK_DESCRIPTION_LEN);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,
-+ value);
-+
-+
-+ /*
-+ *write the port ID:
-+ *PORT_ID0 = display index
-+ *PORT_ID1 = 16bit BDF
-+ *(format MSB->LSB: 8bit Bus, 5bit Device, 3bit Function)
-+ */
-+
-+ value = 0;
-+
-+ set_reg_field_value(value, audio_info->port_id[0],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2,
-+ PORT_ID0);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2,
-+ value);
-+
-+ value = 0;
-+ set_reg_field_value(value, audio_info->port_id[1],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3,
-+ PORT_ID1);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3,
-+ value);
-+
-+ /*write the 18 char monitor string */
-+
-+ value = 0;
-+ set_reg_field_value(value, audio_info->display_name[0],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
-+ DESCRIPTION0);
-+
-+ set_reg_field_value(value, audio_info->display_name[1],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
-+ DESCRIPTION1);
-+
-+ set_reg_field_value(value, audio_info->display_name[2],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
-+ DESCRIPTION2);
-+
-+ set_reg_field_value(value, audio_info->display_name[3],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
-+ DESCRIPTION3);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
-+ value);
-+
-+
-+ value = 0;
-+ set_reg_field_value(value, audio_info->display_name[4],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
-+ DESCRIPTION4);
-+
-+ set_reg_field_value(value, audio_info->display_name[5],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
-+ DESCRIPTION5);
-+
-+ set_reg_field_value(value, audio_info->display_name[6],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
-+ DESCRIPTION6);
-+
-+ set_reg_field_value(value, audio_info->display_name[7],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
-+ DESCRIPTION7);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
-+ value);
-+
-+ value = 0;
-+ set_reg_field_value(value, audio_info->display_name[8],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
-+ DESCRIPTION8);
-+
-+ set_reg_field_value(value, audio_info->display_name[9],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
-+ DESCRIPTION9);
-+
-+ set_reg_field_value(value, audio_info->display_name[10],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
-+ DESCRIPTION10);
-+
-+ set_reg_field_value(value, audio_info->display_name[11],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
-+ DESCRIPTION11);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
-+ value);
-+
-+ value = 0;
-+ set_reg_field_value(value, audio_info->display_name[12],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
-+ DESCRIPTION12);
-+
-+ set_reg_field_value(value, audio_info->display_name[13],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
-+ DESCRIPTION13);
-+
-+ set_reg_field_value(value, audio_info->display_name[14],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
-+ DESCRIPTION14);
-+
-+ set_reg_field_value(value, audio_info->display_name[15],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
-+ DESCRIPTION15);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
-+ value);
-+
-+
-+ value = 0;
-+ set_reg_field_value(value, audio_info->display_name[16],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,
-+ DESCRIPTION16);
-+
-+ set_reg_field_value(value, audio_info->display_name[17],
-+ AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,
-+ DESCRIPTION17);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,
-+ value);
-+
-+}
-+
-+/* setup Azalia HW block */
-+static void setup_azalia(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_pll_info *pll_info,
-+ const struct audio_info *audio_info)
-+{
-+ uint32_t speakers = 0;
-+ uint32_t channels = 0;
-+
-+ if (audio_info == NULL)
-+ /* This should not happen.it does so we don't get BSOD*/
-+ return;
-+
-+ speakers = audio_info->flags.info.ALLSPEAKERS;
-+ channels = dal_audio_hw_ctx_speakers_to_channels(
-+ hw_ctx,
-+ audio_info->flags.speaker_flags).all;
-+
-+ /* setup the audio stream source select (audio -> dig mapping) */
-+ {
-+ const uint32_t addr =
-+ mmAFMT_AUDIO_SRC_CONTROL + engine_offset[engine_id];
-+
-+ uint32_t value = 0;
-+ /*convert one-based index to zero-based */
-+ set_reg_field_value(value,
-+ FROM_BASE(hw_ctx)->azalia_stream_id - 1,
-+ AFMT_AUDIO_SRC_CONTROL,
-+ AFMT_AUDIO_SRC_SELECT);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* Channel allocation */
-+ {
-+ const uint32_t addr =
-+ mmAFMT_AUDIO_PACKET_CONTROL2 + engine_offset[engine_id];
-+ uint32_t value = dal_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value,
-+ channels,
-+ AFMT_AUDIO_PACKET_CONTROL2,
-+ AFMT_AUDIO_CHANNEL_ENABLE);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ configure_azalia(hw_ctx, signal, crtc_info, audio_info);
-+}
-+
-+/* unmute audio */
-+static void unmute_azalia_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ const uint32_t addr = mmAFMT_AUDIO_PACKET_CONTROL +
-+ engine_offset[engine_id];
-+
-+ uint32_t value = 0;
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, 1,
-+ AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+}
-+
-+/* mute audio */
-+static void mute_azalia_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ const uint32_t addr = mmAFMT_AUDIO_PACKET_CONTROL +
-+ engine_offset[engine_id];
-+
-+ uint32_t value = 0;
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, 0,
-+ AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+}
-+
-+/* enable channel splitting mapping */
-+static void setup_channel_splitting_mapping(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ const struct audio_channel_associate_info *audio_mapping,
-+ bool enable)
-+{
-+ uint32_t value = 0;
-+
-+ if ((audio_mapping == NULL || audio_mapping->u32all == 0) && enable)
-+ return;
-+
-+
-+ value = audio_mapping->u32all;
-+
-+ if (enable == false)
-+ /*0xFFFFFFFF;*/
-+ value = MULTI_CHANNEL_SPLIT_NO_ASSO_INFO;
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_ASSOCIATION_INFO,
-+ value);
-+}
-+
-+/* get current channel spliting */
-+static bool get_channel_splitting_mapping(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ struct audio_channel_associate_info *audio_mapping)
-+{
-+ uint32_t value = 0;
-+
-+ if (audio_mapping == NULL)
-+ return false;
-+
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_ASSOCIATION_INFO);
-+
-+ /*0xFFFFFFFF*/
-+ if (get_reg_field_value(value,
-+ AZALIA_F0_CODEC_PIN_ASSOCIATION_INFO,
-+ ASSOCIATION_INFO) !=
-+ MULTI_CHANNEL_SPLIT_NO_ASSO_INFO) {
-+ uint32_t multi_channel01_enable = 0;
-+ uint32_t multi_channel23_enable = 0;
-+ uint32_t multi_channel45_enable = 0;
-+ uint32_t multi_channel67_enable = 0;
-+ /* get the one we set.*/
-+ audio_mapping->u32all = value;
-+
-+ /* check each enable status*/
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE);
-+
-+ multi_channel01_enable = get_reg_field_value(value,
-+ AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE,
-+ MULTICHANNEL01_ENABLE);
-+
-+ multi_channel23_enable = get_reg_field_value(value,
-+ AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE,
-+ MULTICHANNEL23_ENABLE);
-+
-+ multi_channel45_enable = get_reg_field_value(value,
-+ AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE,
-+ MULTICHANNEL45_ENABLE);
-+
-+ multi_channel67_enable = get_reg_field_value(value,
-+ AZALIA_F0_CODEC_PIN_CONTROL_MULTICHANNEL_ENABLE,
-+ MULTICHANNEL67_ENABLE);
-+
-+ if (multi_channel01_enable == 0 &&
-+ multi_channel23_enable == 0 &&
-+ multi_channel45_enable == 0 &&
-+ multi_channel67_enable == 0)
-+ dal_logger_write(hw_ctx->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_COMPONENT_AUDIO,
-+ "Audio driver did not enable multi-channel\n");
-+
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+/* set the payload value for the unsolicited response */
-+static void set_unsolicited_response_payload(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum audio_payload payload)
-+{
-+ /* set the payload value for the unsolicited response
-+ Jack presence is not required to be enabled */
-+ uint32_t value = 0;
-+
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE);
-+
-+ set_reg_field_value(value, payload,
-+ AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE,
-+ UNSOLICITED_RESPONSE_PAYLOAD);
-+
-+ set_reg_field_value(value, 1,
-+ AZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE,
-+ UNSOLICITED_RESPONSE_FORCE);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_UNSOLICITED_RESPONSE_FORCE,
-+ value);
-+}
-+
-+/* initialize HW state */
-+static void hw_initialize(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ uint32_t stream_id = FROM_BASE(hw_ctx)->azalia_stream_id;
-+ uint32_t addr;
-+
-+ /* we only need to program the following registers once, so we only do
-+ it for the first audio stream.*/
-+ if (stream_id != FIRST_AUDIO_STREAM_ID)
-+ return;
-+
-+ /* Suport R5 - 32khz
-+ * Suport R6 - 44.1khz
-+ * Suport R7 - 48khz
-+ */
-+ addr = mmAZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES;
-+ {
-+ uint32_t value;
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, 0x70,
-+ AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES,
-+ AUDIO_RATE_CAPABILITIES);
-+
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /*Keep alive bit to verify HW block in BU. */
-+ addr = mmAZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES;
-+ {
-+ uint32_t value;
-+
-+ value = dal_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, 1,
-+ AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES,
-+ CLKSTOP);
-+
-+ set_reg_field_value(value, 1,
-+ AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES,
-+ EPSS);
-+ dal_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+}
-+
-+/* Assign GTC group and enable GTC value embedding */
-+static void enable_gtc_embedding_with_group(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t group_num,
-+ uint32_t audio_latency)
-+{
-+ /*need to replace the static number with variable */
-+ if (group_num <= 6) {
-+ uint32_t value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING);
-+
-+ set_reg_field_value(
-+ value,
-+ group_num,
-+ AZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING,
-+ PRESENTATION_TIME_EMBEDDING_GROUP);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING,
-+ PRESENTATION_TIME_EMBEDDING_ENABLE);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING,
-+ value);
-+
-+ /*update audio latency to LIPSYNC*/
-+ set_audio_latency(hw_ctx, audio_latency);
-+ } else {
-+ dal_logger_write(
-+ hw_ctx->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_COMPONENT_AUDIO,
-+ "GTC group number %d is too big",
-+ group_num);
-+ }
-+}
-+
-+ /* Disable GTC value embedding */
-+static void disable_gtc_embedding(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ uint32_t value = 0;
-+
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING);
-+
-+ set_reg_field_value(value, 0,
-+ AZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING,
-+ PRESENTATION_TIME_EMBEDDING_ENABLE);
-+
-+ set_reg_field_value(value, 0,
-+ AZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING,
-+ PRESENTATION_TIME_EMBEDDING_GROUP);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_CONVERTER_CONTROL_GTC_EMBEDDING,
-+ value);
-+}
-+
-+/* search pixel clock value for Azalia HDMI Audio */
-+static bool get_azalia_clock_info_hdmi(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t crtc_pixel_clock_in_khz,
-+ uint32_t actual_pixel_clock_in_khz,
-+ struct azalia_clock_info *azalia_clock_info)
-+{
-+ if (azalia_clock_info == NULL)
-+ return false;
-+
-+ /* audio_dto_phase= 24 * 10,000;
-+ * 24MHz in [100Hz] units */
-+ azalia_clock_info->audio_dto_phase =
-+ 24 * 10000;
-+
-+ /* audio_dto_module = PCLKFrequency * 10,000;
-+ * [khz] -> [100Hz] */
-+ azalia_clock_info->audio_dto_module =
-+ actual_pixel_clock_in_khz * 10;
-+
-+ return true;
-+}
-+
-+/* search pixel clock value for Azalia DP Audio */
-+static bool get_azalia_clock_info_dp(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t requested_pixel_clock_in_khz,
-+ const struct audio_pll_info *pll_info,
-+ struct azalia_clock_info *azalia_clock_info)
-+{
-+ if (pll_info == NULL || azalia_clock_info == NULL)
-+ return false;
-+
-+ /* Reported dpDtoSourceClockInkhz value for
-+ * DCE8 already adjusted for SS, do not need any
-+ * adjustment here anymore
-+ */
-+
-+ /*audio_dto_phase = 24 * 10,000;
-+ * 24MHz in [100Hz] units */
-+ azalia_clock_info->audio_dto_phase = 24 * 10000;
-+
-+ /*audio_dto_module = dpDtoSourceClockInkhz * 10,000;
-+ * [khz] ->[100Hz] */
-+ azalia_clock_info->audio_dto_module =
-+ pll_info->dp_dto_source_clock_in_khz * 10;
-+
-+ return true;
-+}
-+
-+static const struct hw_ctx_audio_funcs funcs = {
-+ .destroy = destroy,
-+ .setup_audio_wall_dto =
-+ setup_audio_wall_dto,
-+ .setup_hdmi_audio =
-+ setup_hdmi_audio,
-+ .setup_dp_audio = setup_dp_audio,
-+ .setup_vce_audio = setup_vce_audio,
-+ .enable_azalia_audio =
-+ enable_azalia_audio,
-+ .disable_azalia_audio =
-+ disable_azalia_audio,
-+ .enable_dp_audio =
-+ enable_dp_audio,
-+ .disable_dp_audio =
-+ disable_dp_audio,
-+ .setup_azalia =
-+ setup_azalia,
-+ .disable_az_clock_gating = NULL,
-+ .unmute_azalia_audio =
-+ unmute_azalia_audio,
-+ .mute_azalia_audio =
-+ mute_azalia_audio,
-+ .setup_channel_splitting_mapping =
-+ setup_channel_splitting_mapping,
-+ .get_channel_splitting_mapping =
-+ get_channel_splitting_mapping,
-+ .set_unsolicited_response_payload =
-+ set_unsolicited_response_payload,
-+ .hw_initialize =
-+ hw_initialize,
-+ .enable_gtc_embedding_with_group =
-+ enable_gtc_embedding_with_group,
-+ .disable_gtc_embedding =
-+ disable_gtc_embedding,
-+ .get_azalia_clock_info_hdmi =
-+ get_azalia_clock_info_hdmi,
-+ .get_azalia_clock_info_dp =
-+ get_azalia_clock_info_dp,
-+ .enable_afmt_clock = enable_afmt_clock
-+};
-+
-+static bool construct(
-+ struct hw_ctx_audio_dce110 *hw_ctx,
-+ uint8_t azalia_stream_id,
-+ struct dc_context *ctx)
-+{
-+ struct hw_ctx_audio *base = &hw_ctx->base;
-+
-+ if (!dal_audio_construct_hw_ctx_audio(base))
-+ return false;
-+
-+ base->funcs = &funcs;
-+
-+ /* save audio endpoint or dig front for current dce110 audio object */
-+ hw_ctx->azalia_stream_id = azalia_stream_id;
-+ hw_ctx->base.ctx = ctx;
-+
-+ /* azalia audio endpoints register offsets. azalia is associated with
-+ DIG front. save AUDIO register offset */
-+ switch (azalia_stream_id) {
-+ case 1: {
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_index =
-+ mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX;
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_data =
-+ mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA;
-+ }
-+ break;
-+ case 2: {
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_index =
-+ mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_INDEX;
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_data =
-+ mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_DATA;
-+ }
-+ break;
-+ case 3: {
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_index =
-+ mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_INDEX;
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_data =
-+ mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_DATA;
-+ }
-+ break;
-+ case 4: {
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_index =
-+ mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_INDEX;
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_data =
-+ mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_DATA;
-+ }
-+ break;
-+ default:
-+ dal_logger_write(
-+ hw_ctx->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_AUDIO,
-+ "Invalid Azalia stream ID!");
-+ break;
-+ }
-+
-+ return true;
-+}
-+
-+/* audio_dce110 is derived from audio directly, not via dce80 */
-+struct hw_ctx_audio *dal_hw_ctx_audio_dce110_create(
-+ struct dc_context *ctx,
-+ uint32_t azalia_stream_id)
-+{
-+ /* allocate memory for struc hw_ctx_audio_dce110 */
-+ struct hw_ctx_audio_dce110 *hw_ctx_dce110 =
-+ dc_service_alloc(ctx, sizeof(struct hw_ctx_audio_dce110));
-+
-+ if (!hw_ctx_dce110) {
-+ ASSERT_CRITICAL(hw_ctx_dce110);
-+ return NULL;
-+ }
-+
-+ /*return pointer to hw_ctx_audio back to caller -- audio object */
-+ if (construct(
-+ hw_ctx_dce110, azalia_stream_id, ctx))
-+ return &hw_ctx_dce110->base;
-+
-+ dal_logger_write(
-+ ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_AUDIO,
-+ "Failed to create hw_ctx_audio for DCE11\n");
-+
-+
-+ dc_service_free(ctx, hw_ctx_dce110);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/dce110/hw_ctx_audio_dce110.h b/drivers/gpu/drm/amd/dal/dc/audio/dce110/hw_ctx_audio_dce110.h
-new file mode 100644
-index 0000000..1ad3826
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/dce110/hw_ctx_audio_dce110.h
-@@ -0,0 +1,47 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_CTX_AUDIO_DCE110_H__
-+#define __DAL_HW_CTX_AUDIO_DCE110_H__
-+
-+#include "audio/hw_ctx_audio.h"
-+
-+struct hw_ctx_audio_dce110 {
-+ struct hw_ctx_audio base;
-+
-+ /* azalia stream id 1 based indexing, corresponding to audio GO enumId*/
-+ uint32_t azalia_stream_id;
-+
-+ /* azalia stream endpoint register offsets */
-+ struct azalia_reg_offsets az_mm_reg_offsets;
-+
-+ /* audio encoder block MM register offset -- associate with DIG FRONT */
-+};
-+
-+struct hw_ctx_audio *dal_hw_ctx_audio_dce110_create(
-+ struct dc_context *ctx,
-+ uint32_t azalia_stream_id);
-+
-+#endif /* __DAL_HW_CTX_AUDIO_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/hw_ctx_audio.c b/drivers/gpu/drm/amd/dal/dc/audio/hw_ctx_audio.c
-new file mode 100644
-index 0000000..f1f1298
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/hw_ctx_audio.c
-@@ -0,0 +1,771 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "hw_ctx_audio.h"
-+
-+/* 25.2MHz/1.001*/
-+/* 25.2MHz/1.001*/
-+/* 25.2MHz*/
-+/* 27MHz */
-+/* 27MHz*1.001*/
-+/* 27MHz*1.001*/
-+/* 54MHz*/
-+/* 54MHz*1.001*/
-+/* 74.25MHz/1.001*/
-+/* 74.25MHz*/
-+/* 148.5MHz/1.001*/
-+/* 148.5MHz*/
-+
-+static const struct audio_clock_info audio_clock_info_table[12] = {
-+ {2517, 4576, 28125, 7007, 31250, 6864, 28125},
-+ {2518, 4576, 28125, 7007, 31250, 6864, 28125},
-+ {2520, 4096, 25200, 6272, 28000, 6144, 25200},
-+ {2700, 4096, 27000, 6272, 30000, 6144, 27000},
-+ {2702, 4096, 27027, 6272, 30030, 6144, 27027},
-+ {2703, 4096, 27027, 6272, 30030, 6144, 27027},
-+ {5400, 4096, 54000, 6272, 60000, 6144, 54000},
-+ {5405, 4096, 54054, 6272, 60060, 6144, 54054},
-+ {7417, 11648, 210937, 17836, 234375, 11648, 140625},
-+ {7425, 4096, 74250, 6272, 82500, 6144, 74250},
-+ {14835, 11648, 421875, 8918, 234375, 5824, 140625},
-+ {14850, 4096, 148500, 6272, 165000, 6144, 148500}
-+};
-+
-+static const struct audio_clock_info audio_clock_info_table_36bpc[12] = {
-+ {2517, 9152, 84375, 7007, 48875, 9152, 56250},
-+ {2518, 9152, 84375, 7007, 48875, 9152, 56250},
-+ {2520, 4096, 37800, 6272, 42000, 6144, 37800},
-+ {2700, 4096, 40500, 6272, 45000, 6144, 40500},
-+ {2702, 8192, 81081, 6272, 45045, 8192, 54054},
-+ {2703, 8192, 81081, 6272, 45045, 8192, 54054},
-+ {5400, 4096, 81000, 6272, 90000, 6144, 81000},
-+ {5405, 4096, 81081, 6272, 90090, 6144, 81081},
-+ {7417, 11648, 316406, 17836, 351562, 11648, 210937},
-+ {7425, 4096, 111375, 6272, 123750, 6144, 111375},
-+ {14835, 11648, 632812, 17836, 703125, 11648, 421875},
-+ {14850, 4096, 222750, 6272, 247500, 6144, 222750}
-+};
-+
-+static const struct audio_clock_info audio_clock_info_table_48bpc[12] = {
-+ {2517, 4576, 56250, 7007, 62500, 6864, 56250},
-+ {2518, 4576, 56250, 7007, 62500, 6864, 56250},
-+ {2520, 4096, 50400, 6272, 56000, 6144, 50400},
-+ {2700, 4096, 54000, 6272, 60000, 6144, 54000},
-+ {2702, 4096, 54054, 6267, 60060, 8192, 54054},
-+ {2703, 4096, 54054, 6272, 60060, 8192, 54054},
-+ {5400, 4096, 108000, 6272, 120000, 6144, 108000},
-+ {5405, 4096, 108108, 6272, 120120, 6144, 108108},
-+ {7417, 11648, 421875, 17836, 468750, 11648, 281250},
-+ {7425, 4096, 148500, 6272, 165000, 6144, 148500},
-+ {14835, 11648, 843750, 8918, 468750, 11648, 281250},
-+ {14850, 4096, 297000, 6272, 330000, 6144, 297000}
-+};
-+
-+
-+/***** static function *****/
-+
-+/*
-+ * except of HW context create function, caller will access other functions of
-+ * hw ctx via handle hw_ctx. Memory allocation for struct hw_ctx_audio_dce8x
-+ * will happen in hw_ctx_audio_dce8x. Memory allocation is done with
-+ * dal_audio_create_hw_ctx_audio_dce8x. Memory release is done by caller
-+ * via hw_ctx->functions.destroy(). It will finally use destroy() of
-+ * hw_ctx_audio_dce8x. Therefore, no memory allocate and release happen
-+ * physically at hw ctx base object.
-+ */
-+static void destroy(
-+ struct hw_ctx_audio **ptr)
-+{
-+ /* Attention!
-+ * You must override this method in derived class */
-+}
-+
-+static void setup_audio_wall_dto(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_pll_info *pll_info)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* setup HDMI audio */
-+static void setup_hdmi_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ const struct audio_crtc_info *crtc_info)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+ /* setup DP audio */
-+static void setup_dp_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+ /* setup VCE audio */
-+static void setup_vce_audio(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* enable Azalia audio */
-+static void enable_azalia_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* disable Azalia audio */
-+static void disable_azalia_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* enable DP audio */
-+static void enable_dp_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* disable DP audio */
-+static void disable_dp_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* setup Azalia HW block */
-+static void setup_azalia(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_pll_info *pll_info,
-+ const struct audio_info *audio_info)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* unmute audio */
-+static void unmute_azalia_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* mute audio */
-+static void mute_azalia_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* enable channel splitting mapping */
-+static void setup_channel_splitting_mapping(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ const struct audio_channel_associate_info *audio_mapping,
-+ bool enable)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* get current channel spliting */
-+static bool get_channel_splitting_mapping(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ struct audio_channel_associate_info *audio_mapping)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+}
-+
-+/* set the payload value for the unsolicited response */
-+static void set_unsolicited_response_payload(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum audio_payload payload)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* initialize HW state */
-+static void hw_initialize(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* Assign GTC group and enable GTC value embedding */
-+static void enable_gtc_embedding_with_group(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t groupNum,
-+ uint32_t audioLatency)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* Disable GTC value embedding */
-+static void disable_gtc_embedding(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* Disable Azalia Clock Gating Feature */
-+static void disable_az_clock_gating(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+}
-+
-+/* search pixel clock value for Azalia HDMI Audio */
-+static bool get_azalia_clock_info_hdmi(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t crtc_pixel_clock_in_khz,
-+ uint32_t actual_pixel_clock_in_khz,
-+ struct azalia_clock_info *azalia_clock_info)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+}
-+
-+/* search pixel clock value for Azalia DP Audio */
-+static bool get_azalia_clock_info_dp(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t requested_pixel_clock_in_khz,
-+ const struct audio_pll_info *pll_info,
-+ struct azalia_clock_info *azalia_clock_info)
-+{
-+ /*DCE specific, must be implemented in derived*/
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+}
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+/*****SCOPE : within audio hw context dal-audio-hw-ctx *****/
-+
-+
-+/* check whether specified sample rates can fit into a given timing */
-+void dal_hw_ctx_audio_check_audio_bandwidth(
-+ const struct hw_ctx_audio *hw_ctx,
-+ const struct audio_crtc_info *crtc_info,
-+ uint32_t channel_count,
-+ enum signal_type signal,
-+ union audio_sample_rates *sample_rates)
-+{
-+ switch (signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ dal_audio_hw_ctx_check_audio_bandwidth_hdmi(
-+ hw_ctx, crtc_info, channel_count, sample_rates);
-+ break;
-+ case SIGNAL_TYPE_EDP:
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ dal_audio_hw_ctx_check_audio_bandwidth_dpsst(
-+ hw_ctx, crtc_info, channel_count, sample_rates);
-+ break;
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ dal_audio_hw_ctx_check_audio_bandwidth_dpmst(
-+ hw_ctx, crtc_info, channel_count, sample_rates);
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+/*For HDMI, calculate if specified sample rates can fit into a given timing */
-+void dal_audio_hw_ctx_check_audio_bandwidth_hdmi(
-+ const struct hw_ctx_audio *hw_ctx,
-+ const struct audio_crtc_info *crtc_info,
-+ uint32_t channel_count,
-+ union audio_sample_rates *sample_rates)
-+{
-+ uint32_t samples;
-+ uint32_t h_blank;
-+ bool limit_freq_to_48_khz = false;
-+ bool limit_freq_to_88_2_khz = false;
-+ bool limit_freq_to_96_khz = false;
-+ bool limit_freq_to_174_4_khz = false;
-+
-+ /* For two channels supported return whatever sink support,unmodified*/
-+ if (channel_count > 2) {
-+
-+ /* Based on HDMI spec 1.3 Table 7.5 */
-+ if ((crtc_info->requested_pixel_clock <= 27000) &&
-+ (crtc_info->v_active <= 576) &&
-+ !(crtc_info->interlaced) &&
-+ !(crtc_info->pixel_repetition == 2 ||
-+ crtc_info->pixel_repetition == 4)) {
-+ limit_freq_to_48_khz = true;
-+
-+ } else if ((crtc_info->requested_pixel_clock <= 27000) &&
-+ (crtc_info->v_active <= 576) &&
-+ (crtc_info->interlaced) &&
-+ (crtc_info->pixel_repetition == 2)) {
-+ limit_freq_to_88_2_khz = true;
-+
-+ } else if ((crtc_info->requested_pixel_clock <= 54000) &&
-+ (crtc_info->v_active <= 576) &&
-+ !(crtc_info->interlaced)) {
-+ limit_freq_to_174_4_khz = true;
-+ }
-+ }
-+
-+ /* Also do some calculation for the available Audio Bandwidth for the
-+ * 8 ch (i.e. for the Layout 1 => ch > 2)
-+ */
-+ h_blank = crtc_info->h_total - crtc_info->h_active;
-+
-+ if (crtc_info->pixel_repetition)
-+ h_blank *= crtc_info->pixel_repetition;
-+
-+ /*based on HDMI spec 1.3 Table 7.5 */
-+ h_blank -= 58;
-+ /*for Control Period */
-+ h_blank -= 16;
-+
-+ samples = h_blank * 10;
-+ /* Number of Audio Packets (multiplied by 10) per Line (for 8 ch number
-+ * of Audio samples per line multiplied by 10 - Layout 1)
-+ */
-+ samples /= 32;
-+ samples *= crtc_info->v_active;
-+ /*Number of samples multiplied by 10, per second */
-+ samples *= crtc_info->refresh_rate;
-+ /*Number of Audio samples per second */
-+ samples /= 10;
-+
-+ /* @todo do it after deep color is implemented
-+ * 8xx - deep color bandwidth scaling
-+ * Extra bandwidth is avaliable in deep color b/c link runs faster than
-+ * pixel rate. This has the effect of allowing more tmds characters to
-+ * be transmitted during blank
-+ */
-+
-+ switch (crtc_info->color_depth) {
-+ case COLOR_DEPTH_888:
-+ samples *= 4;
-+ break;
-+ case COLOR_DEPTH_101010:
-+ samples *= 5;
-+ break;
-+ case COLOR_DEPTH_121212:
-+ samples *= 6;
-+ break;
-+ default:
-+ samples *= 4;
-+ break;
-+ }
-+
-+ samples /= 4;
-+
-+ /*check limitation*/
-+ if (samples < 88200)
-+ limit_freq_to_48_khz = true;
-+ else if (samples < 96000)
-+ limit_freq_to_88_2_khz = true;
-+ else if (samples < 176400)
-+ limit_freq_to_96_khz = true;
-+ else if (samples < 192000)
-+ limit_freq_to_174_4_khz = true;
-+
-+ if (sample_rates != NULL) {
-+ /* limit frequencies */
-+ if (limit_freq_to_174_4_khz)
-+ sample_rates->rate.RATE_192 = 0;
-+
-+ if (limit_freq_to_96_khz) {
-+ sample_rates->rate.RATE_192 = 0;
-+ sample_rates->rate.RATE_176_4 = 0;
-+ }
-+ if (limit_freq_to_88_2_khz) {
-+ sample_rates->rate.RATE_192 = 0;
-+ sample_rates->rate.RATE_176_4 = 0;
-+ sample_rates->rate.RATE_96 = 0;
-+ }
-+ if (limit_freq_to_48_khz) {
-+ sample_rates->rate.RATE_192 = 0;
-+ sample_rates->rate.RATE_176_4 = 0;
-+ sample_rates->rate.RATE_96 = 0;
-+ sample_rates->rate.RATE_88_2 = 0;
-+ }
-+ }
-+}
-+
-+/*For DP SST, calculate if specified sample rates can fit into a given timing */
-+void dal_audio_hw_ctx_check_audio_bandwidth_dpsst(
-+ const struct hw_ctx_audio *hw_ctx,
-+ const struct audio_crtc_info *crtc_info,
-+ uint32_t channel_count,
-+ union audio_sample_rates *sample_rates)
-+{
-+ /* do nothing */
-+}
-+
-+/*For DP MST, calculate if specified sample rates can fit into a given timing */
-+void dal_audio_hw_ctx_check_audio_bandwidth_dpmst(
-+ const struct hw_ctx_audio *hw_ctx,
-+ const struct audio_crtc_info *crtc_info,
-+ uint32_t channel_count,
-+ union audio_sample_rates *sample_rates)
-+{
-+ /* do nothing */
-+}
-+
-+/* calculate max number of Audio packets per line */
-+uint32_t dal_audio_hw_ctx_calc_max_audio_packets_per_line(
-+ const struct hw_ctx_audio *hw_ctx,
-+ const struct audio_crtc_info *crtc_info)
-+{
-+ uint32_t max_packets_per_line;
-+
-+ max_packets_per_line =
-+ crtc_info->h_total - crtc_info->h_active;
-+
-+ if (crtc_info->pixel_repetition)
-+ max_packets_per_line *= crtc_info->pixel_repetition;
-+
-+ /* for other hdmi features */
-+ max_packets_per_line -= 58;
-+ /* for Control Period */
-+ max_packets_per_line -= 16;
-+ /* Number of Audio Packets per Line */
-+ max_packets_per_line /= 32;
-+
-+ return max_packets_per_line;
-+}
-+
-+/**
-+* speakersToChannels
-+*
-+* @brief
-+* translate speakers to channels
-+*
-+* FL - Front Left
-+* FR - Front Right
-+* RL - Rear Left
-+* RR - Rear Right
-+* RC - Rear Center
-+* FC - Front Center
-+* FLC - Front Left Center
-+* FRC - Front Right Center
-+* RLC - Rear Left Center
-+* RRC - Rear Right Center
-+* LFE - Low Freq Effect
-+*
-+* FC
-+* FLC FRC
-+* FL FR
-+*
-+* LFE
-+* ()
-+*
-+*
-+* RL RR
-+* RLC RRC
-+* RC
-+*
-+* ch 8 7 6 5 4 3 2 1
-+* 0b00000011 - - - - - - FR FL
-+* 0b00000111 - - - - - LFE FR FL
-+* 0b00001011 - - - - FC - FR FL
-+* 0b00001111 - - - - FC LFE FR FL
-+* 0b00010011 - - - RC - - FR FL
-+* 0b00010111 - - - RC - LFE FR FL
-+* 0b00011011 - - - RC FC - FR FL
-+* 0b00011111 - - - RC FC LFE FR FL
-+* 0b00110011 - - RR RL - - FR FL
-+* 0b00110111 - - RR RL - LFE FR FL
-+* 0b00111011 - - RR RL FC - FR FL
-+* 0b00111111 - - RR RL FC LFE FR FL
-+* 0b01110011 - RC RR RL - - FR FL
-+* 0b01110111 - RC RR RL - LFE FR FL
-+* 0b01111011 - RC RR RL FC - FR FL
-+* 0b01111111 - RC RR RL FC LFE FR FL
-+* 0b11110011 RRC RLC RR RL - - FR FL
-+* 0b11110111 RRC RLC RR RL - LFE FR FL
-+* 0b11111011 RRC RLC RR RL FC - FR FL
-+* 0b11111111 RRC RLC RR RL FC LFE FR FL
-+* 0b11000011 FRC FLC - - - - FR FL
-+* 0b11000111 FRC FLC - - - LFE FR FL
-+* 0b11001011 FRC FLC - - FC - FR FL
-+* 0b11001111 FRC FLC - - FC LFE FR FL
-+* 0b11010011 FRC FLC - RC - - FR FL
-+* 0b11010111 FRC FLC - RC - LFE FR FL
-+* 0b11011011 FRC FLC - RC FC - FR FL
-+* 0b11011111 FRC FLC - RC FC LFE FR FL
-+* 0b11110011 FRC FLC RR RL - - FR FL
-+* 0b11110111 FRC FLC RR RL - LFE FR FL
-+* 0b11111011 FRC FLC RR RL FC - FR FL
-+* 0b11111111 FRC FLC RR RL FC LFE FR FL
-+*
-+* @param
-+* speakers - speaker information as it comes from CEA audio block
-+*/
-+/* translate speakers to channels */
-+union audio_cea_channels dal_audio_hw_ctx_speakers_to_channels(
-+ const struct hw_ctx_audio *hw_ctx,
-+ struct audio_speaker_flags speaker_flags)
-+{
-+ union audio_cea_channels cea_channels = {0};
-+
-+ /* these are one to one */
-+ cea_channels.channels.FL = speaker_flags.FL_FR;
-+ cea_channels.channels.FR = speaker_flags.FL_FR;
-+ cea_channels.channels.LFE = speaker_flags.LFE;
-+ cea_channels.channels.FC = speaker_flags.FC;
-+
-+ /* if Rear Left and Right exist move RC speaker to channel 7
-+ * otherwise to channel 5
-+ */
-+ if (speaker_flags.RL_RR) {
-+ cea_channels.channels.RL_RC = speaker_flags.RL_RR;
-+ cea_channels.channels.RR = speaker_flags.RL_RR;
-+ cea_channels.channels.RC_RLC_FLC = speaker_flags.RC;
-+ } else {
-+ cea_channels.channels.RL_RC = speaker_flags.RC;
-+ }
-+
-+ /* FRONT Left Right Center and REAR Left Right Center are exclusive */
-+ if (speaker_flags.FLC_FRC) {
-+ cea_channels.channels.RC_RLC_FLC = speaker_flags.FLC_FRC;
-+ cea_channels.channels.RRC_FRC = speaker_flags.FLC_FRC;
-+ } else {
-+ cea_channels.channels.RC_RLC_FLC = speaker_flags.RLC_RRC;
-+ cea_channels.channels.RRC_FRC = speaker_flags.RLC_RRC;
-+ }
-+
-+ return cea_channels;
-+}
-+
-+/* check whether specified audio format supported */
-+bool dal_audio_hw_ctx_is_audio_format_supported(
-+ const struct hw_ctx_audio *hw_ctx,
-+ const struct audio_info *audio_info,
-+ enum audio_format_code audio_format_code,
-+ uint32_t *format_index)
-+{
-+ uint32_t index;
-+ uint32_t max_channe_index = 0;
-+ bool found = false;
-+
-+ if (audio_info == NULL)
-+ return found;
-+
-+ /* pass through whole array */
-+ for (index = 0; index < audio_info->mode_count; index++) {
-+ if (audio_info->modes[index].format_code == audio_format_code) {
-+ if (found) {
-+ /* format has multiply entries, choose one with
-+ * highst number of channels */
-+ if (audio_info->modes[index].channel_count >
-+ audio_info->modes[max_channe_index].channel_count) {
-+ max_channe_index = index;
-+ }
-+ } else {
-+ /* format found, save it's index */
-+ found = true;
-+ max_channe_index = index;
-+ }
-+ }
-+ }
-+
-+ /* return index */
-+ if (found && format_index != NULL)
-+ *format_index = max_channe_index;
-+
-+ return found;
-+}
-+
-+/* search pixel clock value for HDMI */
-+bool dal_audio_hw_ctx_get_audio_clock_info(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum dc_color_depth color_depth,
-+ uint32_t crtc_pixel_clock_in_khz,
-+ uint32_t actual_pixel_clock_in_khz,
-+ struct audio_clock_info *audio_clock_info)
-+{
-+ const struct audio_clock_info *clock_info;
-+ uint32_t index;
-+ uint32_t crtc_pixel_clock_in_10khz = crtc_pixel_clock_in_khz / 10;
-+ uint32_t audio_array_size;
-+
-+ if (audio_clock_info == NULL)
-+ return false; /* should not happen */
-+
-+ switch (color_depth) {
-+ case COLOR_DEPTH_161616:
-+ clock_info = audio_clock_info_table_48bpc;
-+ audio_array_size = ARRAY_SIZE(
-+ audio_clock_info_table_48bpc);
-+ break;
-+ case COLOR_DEPTH_121212:
-+ clock_info = audio_clock_info_table_36bpc;
-+ audio_array_size = ARRAY_SIZE(
-+ audio_clock_info_table_36bpc);
-+ break;
-+ default:
-+ clock_info = audio_clock_info_table;
-+ audio_array_size = ARRAY_SIZE(
-+ audio_clock_info_table);
-+ break;
-+ }
-+
-+ if (clock_info != NULL) {
-+ /* search for exact pixel clock in table */
-+ for (index = 0; index < audio_array_size; index++) {
-+ if (clock_info[index].pixel_clock_in_10khz >
-+ crtc_pixel_clock_in_10khz)
-+ break; /* not match */
-+ else if (clock_info[index].pixel_clock_in_10khz ==
-+ crtc_pixel_clock_in_10khz) {
-+ /* match found */
-+ if (audio_clock_info != NULL) {
-+ *audio_clock_info = clock_info[index];
-+ return true;
-+ }
-+ }
-+ }
-+ }
-+
-+
-+ /* not found */
-+ if (actual_pixel_clock_in_khz == 0)
-+ actual_pixel_clock_in_khz = crtc_pixel_clock_in_khz;
-+
-+ /* See HDMI spec the table entry under
-+ * pixel clock of "Other". */
-+ audio_clock_info->pixel_clock_in_10khz =
-+ actual_pixel_clock_in_khz / 10;
-+ audio_clock_info->cts_32khz = actual_pixel_clock_in_khz;
-+ audio_clock_info->cts_44khz = actual_pixel_clock_in_khz;
-+ audio_clock_info->cts_48khz = actual_pixel_clock_in_khz;
-+
-+ audio_clock_info->n_32khz = 4096;
-+ audio_clock_info->n_44khz = 6272;
-+ audio_clock_info->n_48khz = 6144;
-+
-+ return true;
-+}
-+
-+static const struct hw_ctx_audio_funcs funcs = {
-+ .destroy = destroy,
-+ .setup_audio_wall_dto =
-+ setup_audio_wall_dto,
-+ .setup_hdmi_audio =
-+ setup_hdmi_audio,
-+ .setup_dp_audio = setup_dp_audio,
-+ .setup_vce_audio = setup_vce_audio,
-+ .enable_azalia_audio =
-+ enable_azalia_audio,
-+ .disable_azalia_audio =
-+ disable_azalia_audio,
-+ .enable_dp_audio =
-+ enable_dp_audio,
-+ .disable_dp_audio =
-+ disable_dp_audio,
-+ .setup_azalia =
-+ setup_azalia,
-+ .disable_az_clock_gating =
-+ disable_az_clock_gating,
-+ .unmute_azalia_audio =
-+ unmute_azalia_audio,
-+ .mute_azalia_audio =
-+ mute_azalia_audio,
-+ .setup_channel_splitting_mapping =
-+ setup_channel_splitting_mapping,
-+ .get_channel_splitting_mapping =
-+ get_channel_splitting_mapping,
-+ .set_unsolicited_response_payload =
-+ set_unsolicited_response_payload,
-+ .hw_initialize =
-+ hw_initialize,
-+ .enable_gtc_embedding_with_group =
-+ enable_gtc_embedding_with_group,
-+ .disable_gtc_embedding =
-+ disable_gtc_embedding,
-+ .get_azalia_clock_info_hdmi =
-+ get_azalia_clock_info_hdmi,
-+ .get_azalia_clock_info_dp =
-+ get_azalia_clock_info_dp,
-+};
-+/* --- object creator, destroy, construct, destruct --- */
-+
-+bool dal_audio_construct_hw_ctx_audio(
-+ struct hw_ctx_audio *ctx)
-+{
-+ ctx->funcs = &funcs;
-+
-+ /* internal variables */
-+
-+ return true;
-+}
-+
-+void dal_audio_destruct_hw_ctx_audio(
-+ struct hw_ctx_audio *ctx)
-+{
-+ /* nothing to do */
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/hw_ctx_audio.h b/drivers/gpu/drm/amd/dal/dc/audio/hw_ctx_audio.h
-new file mode 100644
-index 0000000..8ab2e58
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/hw_ctx_audio.h
-@@ -0,0 +1,285 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_CTX_AUDIO_H__
-+#define __DAL_HW_CTX_AUDIO_H__
-+
-+#include "include/audio_interface.h"
-+#include "include/link_service_types.h"
-+
-+struct hw_ctx_audio;
-+
-+
-+struct azalia_reg_offsets {
-+ uint32_t azf0endpointx_azalia_f0_codec_endpoint_index;
-+ uint32_t azf0endpointx_azalia_f0_codec_endpoint_data;
-+};
-+
-+/***** hook functions *****/
-+
-+struct hw_ctx_audio_funcs {
-+
-+ /* functions for hw_ctx creation */
-+ void (*destroy)(
-+ struct hw_ctx_audio **ptr);
-+
-+ /***** from dal2 hwcontextaudio.hpp *****/
-+
-+ void (*setup_audio_wall_dto)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_pll_info *pll_info);
-+
-+ /* MM register access read_register write_register */
-+
-+ /***** from dal2 hwcontextaudio_hal.hpp *****/
-+
-+ /* setup HDMI audio */
-+ void (*setup_hdmi_audio)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ const struct audio_crtc_info *crtc_info);
-+
-+ /* setup DP audio */
-+ void (*setup_dp_audio)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id);
-+
-+ /* setup VCE audio */
-+ void (*setup_vce_audio)(
-+ const struct hw_ctx_audio *hw_ctx);
-+
-+ /* enable Azalia audio */
-+ void (*enable_azalia_audio)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id);
-+
-+ /* disable Azalia audio */
-+ void (*disable_azalia_audio)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id);
-+
-+ /* enable DP audio */
-+ void (*enable_dp_audio)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id);
-+
-+ /* disable DP audio */
-+ void (*disable_dp_audio)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id);
-+
-+ /* setup Azalia HW block */
-+ void (*setup_azalia)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_pll_info *pll_info,
-+ const struct audio_info *audio_info);
-+
-+ /* unmute audio */
-+ void (*unmute_azalia_audio)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id);
-+
-+ /* mute audio */
-+ void (*mute_azalia_audio)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id);
-+
-+ /* enable channel splitting mapping */
-+ void (*setup_channel_splitting_mapping)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ const struct audio_channel_associate_info *audio_mapping,
-+ bool enable);
-+
-+ /* get current channel spliting */
-+ bool (*get_channel_splitting_mapping)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ struct audio_channel_associate_info *audio_mapping);
-+
-+ /* set the payload value for the unsolicited response */
-+ void (*set_unsolicited_response_payload)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum audio_payload payload);
-+
-+ /* initialize HW state */
-+ void (*hw_initialize)(
-+ const struct hw_ctx_audio *hw_ctx);
-+
-+ /* check_audio_bandwidth */
-+
-+ /* Assign GTC group and enable GTC value embedding */
-+ void (*enable_gtc_embedding_with_group)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t groupNum,
-+ uint32_t audioLatency);
-+
-+ /* Disable GTC value embedding */
-+ void (*disable_gtc_embedding)(
-+ const struct hw_ctx_audio *hw_ctx);
-+
-+ /* Disable Azalia Clock Gating Feature */
-+ void (*disable_az_clock_gating)(
-+ const struct hw_ctx_audio *hw_ctx);
-+
-+ /* ~~~~ protected: ~~~~*/
-+
-+ /* calc_max_audio_packets_per_line */
-+ /* speakers_to_channels */
-+ /* is_audio_format_supported */
-+ /* get_audio_clock_info */
-+
-+ /* search pixel clock value for Azalia HDMI Audio */
-+ bool (*get_azalia_clock_info_hdmi)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t crtc_pixel_clock_in_khz,
-+ uint32_t actual_pixel_clock_in_khz,
-+ struct azalia_clock_info *azalia_clock_info);
-+
-+ /* search pixel clock value for Azalia DP Audio */
-+ bool (*get_azalia_clock_info_dp)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t requested_pixel_clock_in_khz,
-+ const struct audio_pll_info *pll_info,
-+ struct azalia_clock_info *azalia_clock_info);
-+
-+ void (*enable_afmt_clock)(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ bool enable);
-+
-+ /* @@@@ private: @@@@ */
-+
-+ /* check_audio_bandwidth_hdmi */
-+ /* check_audio_bandwidth_dpsst */
-+ /* check_audio_bandwidth_dpmst */
-+
-+};
-+
-+
-+struct hw_ctx_audio {
-+ const struct hw_ctx_audio_funcs *funcs;
-+ struct dc_context *ctx;
-+
-+ /*audio_clock_infoTable[12];
-+ *audio_clock_infoTable_36bpc[12];
-+ *audio_clock_infoTable_48bpc[12];
-+ *used by hw_ctx_audio.c file only. Will declare as static array
-+ *azaliaclockinfoTable[12] -- not used
-+ *BusNumberMask; BusNumberShift; DeviceNumberMask;
-+ *not used by dce6 and after
-+ */
-+};
-+
-+
-+
-+/* --- object construct, destruct --- */
-+
-+/*
-+ *called by derived audio object for specific ASIC. In case no derived object,
-+ *these two functions do not need exposed.
-+ */
-+bool dal_audio_construct_hw_ctx_audio(
-+ struct hw_ctx_audio *hw_ctx);
-+
-+void dal_audio_destruct_hw_ctx_audio(
-+ struct hw_ctx_audio *hw_ctx);
-+
-+/*
-+ *creator of audio HW context will be implemented by specific ASIC object only.
-+ *Top base or interface object does not have implementation of creator.
-+ */
-+
-+
-+/* --- functions called by audio hw context itself --- */
-+
-+/* MM register access */
-+/*read_register - dal_read_reg */
-+/*write_register - dal_write_reg*/
-+
-+
-+/*check whether specified sample rates can fit into a given timing */
-+void dal_hw_ctx_audio_check_audio_bandwidth(
-+ const struct hw_ctx_audio *hw_ctx,
-+ const struct audio_crtc_info *crtc_info,
-+ uint32_t channel_count,
-+ enum signal_type signal,
-+ union audio_sample_rates *sample_rates);
-+
-+/*For HDMI, calculate if specified sample rates can fit into a given timing */
-+void dal_audio_hw_ctx_check_audio_bandwidth_hdmi(
-+ const struct hw_ctx_audio *hw_ctx,
-+ const struct audio_crtc_info *crtc_info,
-+ uint32_t channel_count,
-+ union audio_sample_rates *sample_rates);
-+
-+/*For DPSST, calculate if specified sample rates can fit into a given timing */
-+void dal_audio_hw_ctx_check_audio_bandwidth_dpsst(
-+ const struct hw_ctx_audio *hw_ctx,
-+ const struct audio_crtc_info *crtc_info,
-+ uint32_t channel_count,
-+ union audio_sample_rates *sample_rates);
-+
-+/*For DPMST, calculate if specified sample rates can fit into a given timing */
-+void dal_audio_hw_ctx_check_audio_bandwidth_dpmst(
-+ const struct hw_ctx_audio *hw_ctx,
-+ const struct audio_crtc_info *crtc_info,
-+ uint32_t channel_count,
-+ union audio_sample_rates *sample_rates);
-+
-+/* calculate max number of Audio packets per line */
-+uint32_t dal_audio_hw_ctx_calc_max_audio_packets_per_line(
-+ const struct hw_ctx_audio *hw_ctx,
-+ const struct audio_crtc_info *crtc_info);
-+
-+/* translate speakers to channels */
-+union audio_cea_channels dal_audio_hw_ctx_speakers_to_channels(
-+ const struct hw_ctx_audio *hw_ctx,
-+ struct audio_speaker_flags speaker_flags);
-+
-+/* check whether specified audio format supported */
-+bool dal_audio_hw_ctx_is_audio_format_supported(
-+ const struct hw_ctx_audio *hw_ctx,
-+ const struct audio_info *audio_info,
-+ enum audio_format_code audio_format_code,
-+ uint32_t *format_index);
-+
-+/* search pixel clock value for HDMI */
-+bool dal_audio_hw_ctx_get_audio_clock_info(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum dc_color_depth color_depth,
-+ uint32_t crtc_pixel_clock_in_khz,
-+ uint32_t actual_pixel_clock_in_khz,
-+ struct audio_clock_info *audio_clock_info);
-+
-+
-+#endif /* __DAL_HW_CTX_AUDIO_H__ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/basics/Makefile b/drivers/gpu/drm/amd/dal/dc/basics/Makefile
-new file mode 100644
-index 0000000..93e2371
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/basics/Makefile
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the 'utils' sub-component of DAL.
-+# It provides the general basic services required by other DAL
-+# subcomponents.
-+
-+BASICS = conversion.o fixpt31_32.o fixpt32_32.o grph_object_id.o logger.o register_logger.o signal_types.o vector.o
-+
-+AMD_DAL_BASICS = $(addprefix $(AMDDALPATH)/dc/basics/,$(BASICS))
-+
-+AMD_DAL_FILES += $(AMD_DAL_BASICS)
-diff --git a/drivers/gpu/drm/amd/dal/dc/basics/conversion.c b/drivers/gpu/drm/amd/dal/dc/basics/conversion.c
-new file mode 100644
-index 0000000..8c38206
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/basics/conversion.c
-@@ -0,0 +1,223 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#define DIVIDER 10000
-+
-+/* S2D13 value in [-3.00...0.9999] */
-+#define S2D13_MIN (-3 * DIVIDER)
-+#define S2D13_MAX (3 * DIVIDER)
-+
-+uint16_t fixed_point_to_int_frac(
-+ struct fixed31_32 arg,
-+ uint8_t integer_bits,
-+ uint8_t fractional_bits)
-+{
-+ int32_t numerator;
-+ int32_t divisor = 1 << fractional_bits;
-+
-+ uint16_t result;
-+
-+ uint16_t d = (uint16_t)dal_fixed31_32_floor(
-+ dal_fixed31_32_abs(
-+ arg));
-+
-+ if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor))
-+ numerator = (uint16_t)dal_fixed31_32_floor(
-+ dal_fixed31_32_mul_int(
-+ arg,
-+ divisor));
-+ else {
-+ numerator = dal_fixed31_32_floor(
-+ dal_fixed31_32_sub(
-+ dal_fixed31_32_from_int(
-+ 1LL << integer_bits),
-+ dal_fixed31_32_recip(
-+ dal_fixed31_32_from_int(
-+ divisor))));
-+ }
-+
-+ if (numerator >= 0)
-+ result = (uint16_t)numerator;
-+ else
-+ result = (uint16_t)(
-+ (1 << (integer_bits + fractional_bits + 1)) + numerator);
-+
-+ if ((result != 0) && dal_fixed31_32_lt(
-+ arg, dal_fixed31_32_zero))
-+ result |= 1 << (integer_bits + fractional_bits);
-+
-+ return result;
-+}
-+/**
-+* convert_float_matrix
-+* This converts a double into HW register spec defined format S2D13.
-+* @param :
-+* @return None
-+*/
-+void convert_float_matrix(
-+ uint16_t *matrix,
-+ struct fixed31_32 *flt,
-+ uint32_t buffer_size)
-+{
-+ const struct fixed31_32 min_2_13 =
-+ dal_fixed31_32_from_fraction(S2D13_MIN, DIVIDER);
-+ const struct fixed31_32 max_2_13 =
-+ dal_fixed31_32_from_fraction(S2D13_MAX, DIVIDER);
-+ uint32_t i;
-+
-+ for (i = 0; i < buffer_size; ++i) {
-+ uint32_t reg_value =
-+ fixed_point_to_int_frac(
-+ dal_fixed31_32_clamp(
-+ flt[i],
-+ min_2_13,
-+ max_2_13),
-+ 2,
-+ 13);
-+
-+ matrix[i] = (uint16_t)reg_value;
-+ }
-+}
-+
-+static void calculate_adjustments_common(
-+ const struct fixed31_32 *ideal_matrix,
-+ const struct dc_csc_adjustments *adjustments,
-+ struct fixed31_32 *matrix)
-+{
-+ const struct fixed31_32 sin_hue =
-+ dal_fixed31_32_sin(adjustments->hue);
-+ const struct fixed31_32 cos_hue =
-+ dal_fixed31_32_cos(adjustments->hue);
-+
-+ const struct fixed31_32 multiplier =
-+ dal_fixed31_32_mul(
-+ adjustments->contrast,
-+ adjustments->saturation);
-+
-+ matrix[0] = dal_fixed31_32_mul(
-+ ideal_matrix[0],
-+ adjustments->contrast);
-+
-+ matrix[1] = dal_fixed31_32_mul(
-+ ideal_matrix[1],
-+ adjustments->contrast);
-+
-+ matrix[2] = dal_fixed31_32_mul(
-+ ideal_matrix[2],
-+ adjustments->contrast);
-+
-+ matrix[4] = dal_fixed31_32_mul(
-+ multiplier,
-+ dal_fixed31_32_add(
-+ dal_fixed31_32_mul(
-+ ideal_matrix[8],
-+ sin_hue),
-+ dal_fixed31_32_mul(
-+ ideal_matrix[4],
-+ cos_hue)));
-+
-+ matrix[5] = dal_fixed31_32_mul(
-+ multiplier,
-+ dal_fixed31_32_add(
-+ dal_fixed31_32_mul(
-+ ideal_matrix[9],
-+ sin_hue),
-+ dal_fixed31_32_mul(
-+ ideal_matrix[5],
-+ cos_hue)));
-+
-+ matrix[6] = dal_fixed31_32_mul(
-+ multiplier,
-+ dal_fixed31_32_add(
-+ dal_fixed31_32_mul(
-+ ideal_matrix[10],
-+ sin_hue),
-+ dal_fixed31_32_mul(
-+ ideal_matrix[6],
-+ cos_hue)));
-+
-+ matrix[7] = ideal_matrix[7];
-+
-+ matrix[8] = dal_fixed31_32_mul(
-+ multiplier,
-+ dal_fixed31_32_sub(
-+ dal_fixed31_32_mul(
-+ ideal_matrix[8],
-+ cos_hue),
-+ dal_fixed31_32_mul(
-+ ideal_matrix[4],
-+ sin_hue)));
-+
-+ matrix[9] = dal_fixed31_32_mul(
-+ multiplier,
-+ dal_fixed31_32_sub(
-+ dal_fixed31_32_mul(
-+ ideal_matrix[9],
-+ cos_hue),
-+ dal_fixed31_32_mul(
-+ ideal_matrix[5],
-+ sin_hue)));
-+
-+ matrix[10] = dal_fixed31_32_mul(
-+ multiplier,
-+ dal_fixed31_32_sub(
-+ dal_fixed31_32_mul(
-+ ideal_matrix[10],
-+ cos_hue),
-+ dal_fixed31_32_mul(
-+ ideal_matrix[6],
-+ sin_hue)));
-+
-+ matrix[11] = ideal_matrix[11];
-+}
-+
-+void calculate_adjustments(
-+ const struct fixed31_32 *ideal_matrix,
-+ const struct dc_csc_adjustments *adjustments,
-+ struct fixed31_32 *matrix)
-+{
-+ calculate_adjustments_common(ideal_matrix, adjustments, matrix);
-+
-+ matrix[3] = dal_fixed31_32_add(
-+ ideal_matrix[3],
-+ dal_fixed31_32_mul(
-+ adjustments->brightness,
-+ dal_fixed31_32_from_fraction(86, 100)));
-+}
-+
-+void calculate_adjustments_y_only(
-+ const struct fixed31_32 *ideal_matrix,
-+ const struct dc_csc_adjustments *adjustments,
-+ struct fixed31_32 *matrix)
-+{
-+ calculate_adjustments_common(ideal_matrix, adjustments, matrix);
-+
-+ matrix[3] = dal_fixed31_32_add(
-+ ideal_matrix[3],
-+ adjustments->brightness);
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/basics/conversion.h b/drivers/gpu/drm/amd/dal/dc/basics/conversion.h
-new file mode 100644
-index 0000000..24ff473
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/basics/conversion.h
-@@ -0,0 +1,49 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_CONVERSION_H__
-+#define __DAL_CONVERSION_H__
-+
-+uint16_t fixed_point_to_int_frac(
-+ struct fixed31_32 arg,
-+ uint8_t integer_bits,
-+ uint8_t fractional_bits);
-+
-+void convert_float_matrix(
-+ uint16_t *matrix,
-+ struct fixed31_32 *flt,
-+ uint32_t buffer_size);
-+
-+void calculate_adjustments(
-+ const struct fixed31_32 *ideal_matrix,
-+ const struct dc_csc_adjustments *adjustments,
-+ struct fixed31_32 *matrix);
-+
-+void calculate_adjustments_y_only(
-+ const struct fixed31_32 *ideal_matrix,
-+ const struct dc_csc_adjustments *adjustments,
-+ struct fixed31_32 *matrix);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/basics/fixpt31_32.c b/drivers/gpu/drm/amd/dal/dc/basics/fixpt31_32.c
-new file mode 100644
-index 0000000..6ce75b3
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/basics/fixpt31_32.c
-@@ -0,0 +1,692 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/fixed31_32.h"
-+
-+static inline uint64_t abs_i64(
-+ int64_t arg)
-+{
-+ if (arg > 0)
-+ return (uint64_t)arg;
-+ else
-+ return (uint64_t)(-arg);
-+}
-+
-+/*
-+ * @brief
-+ * result = dividend / divisor
-+ * *remainder = dividend % divisor
-+ */
-+static inline uint64_t complete_integer_division_u64(
-+ uint64_t dividend,
-+ uint64_t divisor,
-+ uint64_t *remainder)
-+{
-+ uint64_t result;
-+
-+ ASSERT(divisor);
-+
-+ result = div64_u64_rem(dividend, divisor, remainder);
-+
-+ return result;
-+}
-+
-+#define BITS_PER_FRACTIONAL_PART \
-+ 32
-+
-+#define FRACTIONAL_PART_MASK \
-+ ((1ULL << BITS_PER_FRACTIONAL_PART) - 1)
-+
-+#define GET_INTEGER_PART(x) \
-+ ((x) >> BITS_PER_FRACTIONAL_PART)
-+
-+#define GET_FRACTIONAL_PART(x) \
-+ (FRACTIONAL_PART_MASK & (x))
-+
-+struct fixed31_32 dal_fixed31_32_from_fraction(
-+ int64_t numerator,
-+ int64_t denominator)
-+{
-+ struct fixed31_32 res;
-+
-+ bool arg1_negative = numerator < 0;
-+ bool arg2_negative = denominator < 0;
-+
-+ uint64_t arg1_value = arg1_negative ? -numerator : numerator;
-+ uint64_t arg2_value = arg2_negative ? -denominator : denominator;
-+
-+ uint64_t remainder;
-+
-+ /* determine integer part */
-+
-+ uint64_t res_value = complete_integer_division_u64(
-+ arg1_value, arg2_value, &remainder);
-+
-+ ASSERT(res_value <= LONG_MAX);
-+
-+ /* determine fractional part */
-+ {
-+ uint32_t i = BITS_PER_FRACTIONAL_PART;
-+
-+ do {
-+ remainder <<= 1;
-+
-+ res_value <<= 1;
-+
-+ if (remainder >= arg2_value) {
-+ res_value |= 1;
-+ remainder -= arg2_value;
-+ }
-+ } while (--i != 0);
-+ }
-+
-+ /* round up LSB */
-+ {
-+ uint64_t summand = (remainder << 1) >= arg2_value;
-+
-+ ASSERT(res_value <= LLONG_MAX - summand);
-+
-+ res_value += summand;
-+ }
-+
-+ res.value = (int64_t)res_value;
-+
-+ if (arg1_negative ^ arg2_negative)
-+ res.value = -res.value;
-+
-+ return res;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_from_int(
-+ int64_t arg)
-+{
-+ struct fixed31_32 res;
-+
-+ ASSERT((LONG_MIN <= arg) && (arg <= LONG_MAX));
-+
-+ res.value = arg << BITS_PER_FRACTIONAL_PART;
-+
-+ return res;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_neg(
-+ struct fixed31_32 arg)
-+{
-+ struct fixed31_32 res;
-+
-+ res.value = -arg.value;
-+
-+ return res;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_abs(
-+ struct fixed31_32 arg)
-+{
-+ if (arg.value < 0)
-+ return dal_fixed31_32_neg(arg);
-+ else
-+ return arg;
-+}
-+
-+bool dal_fixed31_32_lt(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2)
-+{
-+ return arg1.value < arg2.value;
-+}
-+
-+bool dal_fixed31_32_le(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2)
-+{
-+ return arg1.value <= arg2.value;
-+}
-+
-+bool dal_fixed31_32_eq(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2)
-+{
-+ return arg1.value == arg2.value;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_min(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2)
-+{
-+ if (arg1.value <= arg2.value)
-+ return arg1;
-+ else
-+ return arg2;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_max(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2)
-+{
-+ if (arg1.value <= arg2.value)
-+ return arg2;
-+ else
-+ return arg1;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_clamp(
-+ struct fixed31_32 arg,
-+ struct fixed31_32 min_value,
-+ struct fixed31_32 max_value)
-+{
-+ if (dal_fixed31_32_le(arg, min_value))
-+ return min_value;
-+ else if (dal_fixed31_32_le(max_value, arg))
-+ return max_value;
-+ else
-+ return arg;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_shl(
-+ struct fixed31_32 arg,
-+ uint8_t shift)
-+{
-+ struct fixed31_32 res;
-+
-+ ASSERT(((arg.value >= 0) && (arg.value <= LLONG_MAX >> shift)) ||
-+ ((arg.value < 0) && (arg.value >= LLONG_MIN >> shift)));
-+
-+ res.value = arg.value << shift;
-+
-+ return res;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_shr(
-+ struct fixed31_32 arg,
-+ uint8_t shift)
-+{
-+ struct fixed31_32 res;
-+
-+ ASSERT(shift < 64);
-+
-+ res.value = arg.value >> shift;
-+
-+ return res;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_add(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2)
-+{
-+ struct fixed31_32 res;
-+
-+ ASSERT(((arg1.value >= 0) && (LLONG_MAX - arg1.value >= arg2.value)) ||
-+ ((arg1.value < 0) && (LLONG_MIN - arg1.value <= arg2.value)));
-+
-+ res.value = arg1.value + arg2.value;
-+
-+ return res;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_sub_int(
-+ struct fixed31_32 arg1,
-+ int32_t arg2)
-+{
-+ return dal_fixed31_32_sub(
-+ arg1,
-+ dal_fixed31_32_from_int(arg2));
-+}
-+
-+struct fixed31_32 dal_fixed31_32_sub(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2)
-+{
-+ struct fixed31_32 res;
-+
-+ ASSERT(((arg2.value >= 0) && (LLONG_MIN + arg2.value <= arg1.value)) ||
-+ ((arg2.value < 0) && (LLONG_MAX + arg2.value >= arg1.value)));
-+
-+ res.value = arg1.value - arg2.value;
-+
-+ return res;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_mul_int(
-+ struct fixed31_32 arg1,
-+ int32_t arg2)
-+{
-+ return dal_fixed31_32_mul(
-+ arg1,
-+ dal_fixed31_32_from_int(arg2));
-+}
-+
-+struct fixed31_32 dal_fixed31_32_mul(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2)
-+{
-+ struct fixed31_32 res;
-+
-+ bool arg1_negative = arg1.value < 0;
-+ bool arg2_negative = arg2.value < 0;
-+
-+ uint64_t arg1_value = arg1_negative ? -arg1.value : arg1.value;
-+ uint64_t arg2_value = arg2_negative ? -arg2.value : arg2.value;
-+
-+ uint64_t arg1_int = GET_INTEGER_PART(arg1_value);
-+ uint64_t arg2_int = GET_INTEGER_PART(arg2_value);
-+
-+ uint64_t arg1_fra = GET_FRACTIONAL_PART(arg1_value);
-+ uint64_t arg2_fra = GET_FRACTIONAL_PART(arg2_value);
-+
-+ uint64_t tmp;
-+
-+ res.value = arg1_int * arg2_int;
-+
-+ ASSERT(res.value <= LONG_MAX);
-+
-+ res.value <<= BITS_PER_FRACTIONAL_PART;
-+
-+ tmp = arg1_int * arg2_fra;
-+
-+ ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value));
-+
-+ res.value += tmp;
-+
-+ tmp = arg2_int * arg1_fra;
-+
-+ ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value));
-+
-+ res.value += tmp;
-+
-+ tmp = arg1_fra * arg2_fra;
-+
-+ tmp = (tmp >> BITS_PER_FRACTIONAL_PART) +
-+ (tmp >= (uint64_t)dal_fixed31_32_half.value);
-+
-+ ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value));
-+
-+ res.value += tmp;
-+
-+ if (arg1_negative ^ arg2_negative)
-+ res.value = -res.value;
-+
-+ return res;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_sqr(
-+ struct fixed31_32 arg)
-+{
-+ struct fixed31_32 res;
-+
-+ uint64_t arg_value = abs_i64(arg.value);
-+
-+ uint64_t arg_int = GET_INTEGER_PART(arg_value);
-+
-+ uint64_t arg_fra = GET_FRACTIONAL_PART(arg_value);
-+
-+ uint64_t tmp;
-+
-+ res.value = arg_int * arg_int;
-+
-+ ASSERT(res.value <= LONG_MAX);
-+
-+ res.value <<= BITS_PER_FRACTIONAL_PART;
-+
-+ tmp = arg_int * arg_fra;
-+
-+ ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value));
-+
-+ res.value += tmp;
-+
-+ ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value));
-+
-+ res.value += tmp;
-+
-+ tmp = arg_fra * arg_fra;
-+
-+ tmp = (tmp >> BITS_PER_FRACTIONAL_PART) +
-+ (tmp >= (uint64_t)dal_fixed31_32_half.value);
-+
-+ ASSERT(tmp <= (uint64_t)(LLONG_MAX - res.value));
-+
-+ res.value += tmp;
-+
-+ return res;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_div_int(
-+ struct fixed31_32 arg1,
-+ int64_t arg2)
-+{
-+ return dal_fixed31_32_from_fraction(
-+ arg1.value,
-+ dal_fixed31_32_from_int(arg2).value);
-+}
-+
-+struct fixed31_32 dal_fixed31_32_div(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2)
-+{
-+ return dal_fixed31_32_from_fraction(
-+ arg1.value,
-+ arg2.value);
-+}
-+
-+struct fixed31_32 dal_fixed31_32_recip(
-+ struct fixed31_32 arg)
-+{
-+ /*
-+ * @note
-+ * Good idea to use Newton's method
-+ */
-+
-+ ASSERT(arg.value);
-+
-+ return dal_fixed31_32_from_fraction(
-+ dal_fixed31_32_one.value,
-+ arg.value);
-+}
-+
-+struct fixed31_32 dal_fixed31_32_sinc(
-+ struct fixed31_32 arg)
-+{
-+ struct fixed31_32 square;
-+
-+ struct fixed31_32 res = dal_fixed31_32_one;
-+
-+ int32_t n = 27;
-+
-+ struct fixed31_32 arg_norm = arg;
-+
-+ if (dal_fixed31_32_le(
-+ dal_fixed31_32_two_pi,
-+ dal_fixed31_32_abs(arg))) {
-+ arg_norm = dal_fixed31_32_sub(
-+ arg_norm,
-+ dal_fixed31_32_mul_int(
-+ dal_fixed31_32_two_pi,
-+ (int32_t)div64_s64(
-+ arg_norm.value,
-+ dal_fixed31_32_two_pi.value)));
-+ }
-+
-+ square = dal_fixed31_32_sqr(arg_norm);
-+
-+ do {
-+ res = dal_fixed31_32_sub(
-+ dal_fixed31_32_one,
-+ dal_fixed31_32_div_int(
-+ dal_fixed31_32_mul(
-+ square,
-+ res),
-+ n * (n - 1)));
-+
-+ n -= 2;
-+ } while (n > 2);
-+
-+ if (arg.value != arg_norm.value)
-+ res = dal_fixed31_32_div(
-+ dal_fixed31_32_mul(res, arg_norm),
-+ arg);
-+
-+ return res;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_sin(
-+ struct fixed31_32 arg)
-+{
-+ return dal_fixed31_32_mul(
-+ arg,
-+ dal_fixed31_32_sinc(arg));
-+}
-+
-+struct fixed31_32 dal_fixed31_32_cos(
-+ struct fixed31_32 arg)
-+{
-+ /* TODO implement argument normalization */
-+
-+ const struct fixed31_32 square = dal_fixed31_32_sqr(arg);
-+
-+ struct fixed31_32 res = dal_fixed31_32_one;
-+
-+ int32_t n = 26;
-+
-+ do {
-+ res = dal_fixed31_32_sub(
-+ dal_fixed31_32_one,
-+ dal_fixed31_32_div_int(
-+ dal_fixed31_32_mul(
-+ square,
-+ res),
-+ n * (n - 1)));
-+
-+ n -= 2;
-+ } while (n != 0);
-+
-+ return res;
-+}
-+
-+/*
-+ * @brief
-+ * result = exp(arg),
-+ * where abs(arg) < 1
-+ *
-+ * Calculated as Taylor series.
-+ */
-+static struct fixed31_32 fixed31_32_exp_from_taylor_series(
-+ struct fixed31_32 arg)
-+{
-+ uint32_t n = 9;
-+
-+ struct fixed31_32 res = dal_fixed31_32_from_fraction(
-+ n + 2,
-+ n + 1);
-+ /* TODO find correct res */
-+
-+ ASSERT(dal_fixed31_32_lt(arg, dal_fixed31_32_one));
-+
-+ do
-+ res = dal_fixed31_32_add(
-+ dal_fixed31_32_one,
-+ dal_fixed31_32_div_int(
-+ dal_fixed31_32_mul(
-+ arg,
-+ res),
-+ n));
-+ while (--n != 1);
-+
-+ return dal_fixed31_32_add(
-+ dal_fixed31_32_one,
-+ dal_fixed31_32_mul(
-+ arg,
-+ res));
-+}
-+
-+struct fixed31_32 dal_fixed31_32_exp(
-+ struct fixed31_32 arg)
-+{
-+ /*
-+ * @brief
-+ * Main equation is:
-+ * exp(x) = exp(r + m * ln(2)) = (1 << m) * exp(r),
-+ * where m = round(x / ln(2)), r = x - m * ln(2)
-+ */
-+
-+ if (dal_fixed31_32_le(
-+ dal_fixed31_32_ln2_div_2,
-+ dal_fixed31_32_abs(arg))) {
-+ int32_t m = dal_fixed31_32_round(
-+ dal_fixed31_32_div(
-+ arg,
-+ dal_fixed31_32_ln2));
-+
-+ struct fixed31_32 r = dal_fixed31_32_sub(
-+ arg,
-+ dal_fixed31_32_mul_int(
-+ dal_fixed31_32_ln2,
-+ m));
-+
-+ ASSERT(m != 0);
-+
-+ ASSERT(dal_fixed31_32_lt(
-+ dal_fixed31_32_abs(r),
-+ dal_fixed31_32_one));
-+
-+ if (m > 0)
-+ return dal_fixed31_32_shl(
-+ fixed31_32_exp_from_taylor_series(r),
-+ (uint8_t)m);
-+ else
-+ return dal_fixed31_32_div_int(
-+ fixed31_32_exp_from_taylor_series(r),
-+ 1LL << -m);
-+ } else if (arg.value != 0)
-+ return fixed31_32_exp_from_taylor_series(arg);
-+ else
-+ return dal_fixed31_32_one;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_log(
-+ struct fixed31_32 arg)
-+{
-+ struct fixed31_32 res = dal_fixed31_32_neg(dal_fixed31_32_one);
-+ /* TODO improve 1st estimation */
-+
-+ struct fixed31_32 error;
-+
-+ ASSERT(arg.value > 0);
-+ /* TODO if arg is negative, return NaN */
-+ /* TODO if arg is zero, return -INF */
-+
-+ do {
-+ struct fixed31_32 res1 = dal_fixed31_32_add(
-+ dal_fixed31_32_sub(
-+ res,
-+ dal_fixed31_32_one),
-+ dal_fixed31_32_div(
-+ arg,
-+ dal_fixed31_32_exp(res)));
-+
-+ error = dal_fixed31_32_sub(
-+ res,
-+ res1);
-+
-+ res = res1;
-+ /* TODO determine max_allowed_error based on quality of exp() */
-+ } while (abs_i64(error.value) > 100ULL);
-+
-+ return res;
-+}
-+
-+struct fixed31_32 dal_fixed31_32_pow(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2)
-+{
-+ return dal_fixed31_32_exp(
-+ dal_fixed31_32_mul(
-+ dal_fixed31_32_log(arg1),
-+ arg2));
-+}
-+
-+int32_t dal_fixed31_32_floor(
-+ struct fixed31_32 arg)
-+{
-+ uint64_t arg_value = abs_i64(arg.value);
-+
-+ if (arg.value >= 0)
-+ return (int32_t)GET_INTEGER_PART(arg_value);
-+ else
-+ return -(int32_t)GET_INTEGER_PART(arg_value);
-+}
-+
-+int32_t dal_fixed31_32_round(
-+ struct fixed31_32 arg)
-+{
-+ uint64_t arg_value = abs_i64(arg.value);
-+
-+ const int64_t summand = dal_fixed31_32_half.value;
-+
-+ ASSERT(LLONG_MAX - (int64_t)arg_value >= summand);
-+
-+ arg_value += summand;
-+
-+ if (arg.value >= 0)
-+ return (int32_t)GET_INTEGER_PART(arg_value);
-+ else
-+ return -(int32_t)GET_INTEGER_PART(arg_value);
-+}
-+
-+int32_t dal_fixed31_32_ceil(
-+ struct fixed31_32 arg)
-+{
-+ uint64_t arg_value = abs_i64(arg.value);
-+
-+ const int64_t summand = dal_fixed31_32_one.value -
-+ dal_fixed31_32_epsilon.value;
-+
-+ ASSERT(LLONG_MAX - (int64_t)arg_value >= summand);
-+
-+ arg_value += summand;
-+
-+ if (arg.value >= 0)
-+ return (int32_t)GET_INTEGER_PART(arg_value);
-+ else
-+ return -(int32_t)GET_INTEGER_PART(arg_value);
-+}
-+
-+/* this function is a generic helper to translate fixed point value to
-+ * specified integer format that will consist of integer_bits integer part and
-+ * fractional_bits fractional part. For example it is used in
-+ * dal_fixed31_32_u2d19 to receive 2 bits integer part and 19 bits fractional
-+ * part in 32 bits. It is used in hw programming (scaler)
-+ */
-+
-+static inline uint32_t ux_dy(
-+ int64_t value,
-+ uint32_t integer_bits,
-+ uint32_t fractional_bits)
-+{
-+ /* 1. create mask of integer part */
-+ uint32_t result =
-+ (1 << integer_bits) - 1;
-+ /* 2. mask out fractional part */
-+ uint32_t fractional_part = FRACTIONAL_PART_MASK & value;
-+ /* 3. shrink fixed point integer part to be of integer_bits width*/
-+ result &= GET_INTEGER_PART(value);
-+ /* 4. make space for fractional part to be filled in after integer */
-+ result <<= fractional_bits;
-+ /* 5. shrink fixed point fractional part to of fractional_bits width*/
-+ fractional_part >>= BITS_PER_FRACTIONAL_PART - fractional_bits;
-+ /* 6. merge the result */
-+ return result | fractional_part;
-+}
-+
-+uint32_t dal_fixed31_32_u2d19(
-+ struct fixed31_32 arg)
-+{
-+ return ux_dy(arg.value, 2, 19);
-+}
-+
-+uint32_t dal_fixed31_32_u0d19(
-+ struct fixed31_32 arg)
-+{
-+ return ux_dy(arg.value, 0, 19);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/basics/fixpt32_32.c b/drivers/gpu/drm/amd/dal/dc/basics/fixpt32_32.c
-new file mode 100644
-index 0000000..1140132
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/basics/fixpt32_32.c
-@@ -0,0 +1,223 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/fixed32_32.h"
-+
-+static uint64_t u64_div(uint64_t n, uint64_t d)
-+{
-+ uint32_t i = 0;
-+ uint64_t r;
-+ uint64_t q = div64_u64_rem(n, d, &r);
-+
-+ for (i = 0; i < 32; ++i) {
-+ uint64_t sbit = q & (1ULL<<63);
-+
-+ r <<= 1;
-+ r |= sbit ? 1 : 0;
-+ q <<= 1;
-+ if (r >= d) {
-+ r -= d;
-+ q |= 1;
-+ }
-+ }
-+
-+ if (2*r >= d)
-+ q += 1;
-+ return q;
-+}
-+
-+struct fixed32_32 dal_fixed32_32_from_fraction(uint32_t n, uint32_t d)
-+{
-+ struct fixed32_32 fx;
-+
-+ fx.value = u64_div((uint64_t)n << 32, (uint64_t)d << 32);
-+ return fx;
-+}
-+
-+struct fixed32_32 dal_fixed32_32_from_int(uint32_t value)
-+{
-+ struct fixed32_32 fx;
-+
-+ fx.value = (uint64_t)value<<32;
-+ return fx;
-+}
-+
-+struct fixed32_32 dal_fixed32_32_add(
-+ struct fixed32_32 lhs,
-+ struct fixed32_32 rhs)
-+{
-+ struct fixed32_32 fx = {lhs.value + rhs.value};
-+
-+ ASSERT(fx.value >= rhs.value);
-+ return fx;
-+}
-+
-+struct fixed32_32 dal_fixed32_32_add_int(struct fixed32_32 lhs, uint32_t rhs)
-+{
-+ struct fixed32_32 fx = {lhs.value + ((uint64_t)rhs << 32)};
-+
-+ ASSERT(fx.value >= (uint64_t)rhs << 32);
-+ return fx;
-+
-+}
-+struct fixed32_32 dal_fixed32_32_sub(
-+ struct fixed32_32 lhs,
-+ struct fixed32_32 rhs)
-+{
-+ struct fixed32_32 fx;
-+
-+ ASSERT(lhs.value >= rhs.value);
-+ fx.value = lhs.value - rhs.value;
-+ return fx;
-+}
-+
-+struct fixed32_32 dal_fixed32_32_sub_int(struct fixed32_32 lhs, uint32_t rhs)
-+{
-+ struct fixed32_32 fx;
-+
-+ ASSERT(lhs.value >= ((uint64_t)rhs<<32));
-+ fx.value = lhs.value - ((uint64_t)rhs<<32);
-+ return fx;
-+}
-+
-+struct fixed32_32 dal_fixed32_32_mul(
-+ struct fixed32_32 lhs,
-+ struct fixed32_32 rhs)
-+{
-+ struct fixed32_32 fx;
-+ uint64_t lhs_int = lhs.value>>32;
-+ uint64_t lhs_frac = (uint32_t)lhs.value;
-+ uint64_t rhs_int = rhs.value>>32;
-+ uint64_t rhs_frac = (uint32_t)rhs.value;
-+ uint64_t ahbh = lhs_int * rhs_int;
-+ uint64_t ahbl = lhs_int * rhs_frac;
-+ uint64_t albh = lhs_frac * rhs_int;
-+ uint64_t albl = lhs_frac * rhs_frac;
-+
-+ ASSERT((ahbh>>32) == 0);
-+
-+ fx.value = (ahbh<<32) + ahbl + albh + (albl>>32);
-+ return fx;
-+
-+}
-+
-+struct fixed32_32 dal_fixed32_32_mul_int(struct fixed32_32 lhs, uint32_t rhs)
-+{
-+ struct fixed32_32 fx;
-+ uint64_t lhsi = (lhs.value>>32) * (uint64_t)rhs;
-+ uint64_t lhsf;
-+
-+ ASSERT((lhsi>>32) == 0);
-+ lhsf = ((uint32_t)lhs.value) * (uint64_t)rhs;
-+ ASSERT((lhsi<<32) + lhsf >= lhsf);
-+ fx.value = (lhsi<<32) + lhsf;
-+ return fx;
-+}
-+
-+
-+
-+struct fixed32_32 dal_fixed32_32_div(
-+ struct fixed32_32 lhs,
-+ struct fixed32_32 rhs)
-+{
-+ struct fixed32_32 fx;
-+
-+ fx.value = u64_div(lhs.value, rhs.value);
-+ return fx;
-+}
-+
-+struct fixed32_32 dal_fixed32_32_div_int(struct fixed32_32 lhs, uint32_t rhs)
-+{
-+ struct fixed32_32 fx;
-+
-+ fx.value = u64_div(lhs.value, (uint64_t)rhs << 32);
-+ return fx;
-+}
-+
-+struct fixed32_32 dal_fixed32_32_min(
-+ struct fixed32_32 lhs,
-+ struct fixed32_32 rhs)
-+{
-+ return (lhs.value < rhs.value) ? lhs : rhs;
-+}
-+
-+struct fixed32_32 dal_fixed32_32_max(
-+ struct fixed32_32 lhs,
-+ struct fixed32_32 rhs)
-+{
-+ return (lhs.value > rhs.value) ? lhs : rhs;
-+}
-+
-+bool dal_fixed32_32_gt(struct fixed32_32 lhs, struct fixed32_32 rhs)
-+{
-+ return lhs.value > rhs.value;
-+}
-+bool dal_fixed32_32_gt_int(struct fixed32_32 lhs, uint32_t rhs)
-+{
-+ return lhs.value > ((uint64_t)rhs<<32);
-+}
-+
-+bool dal_fixed32_32_lt(struct fixed32_32 lhs, struct fixed32_32 rhs)
-+{
-+ return lhs.value < rhs.value;
-+}
-+
-+bool dal_fixed32_32_le(struct fixed32_32 lhs, struct fixed32_32 rhs)
-+{
-+ return lhs.value <= rhs.value;
-+}
-+
-+bool dal_fixed32_32_lt_int(struct fixed32_32 lhs, uint32_t rhs)
-+{
-+ return lhs.value < ((uint64_t)rhs<<32);
-+}
-+
-+bool dal_fixed32_32_le_int(struct fixed32_32 lhs, uint32_t rhs)
-+{
-+ return lhs.value <= ((uint64_t)rhs<<32);
-+}
-+
-+uint32_t dal_fixed32_32_ceil(struct fixed32_32 v)
-+{
-+ ASSERT((uint32_t)v.value ? (v.value >> 32) + 1 >= 1 : true);
-+ return (v.value>>32) + ((uint32_t)v.value ? 1 : 0);
-+}
-+
-+uint32_t dal_fixed32_32_floor(struct fixed32_32 v)
-+{
-+ return v.value>>32;
-+}
-+
-+uint32_t dal_fixed32_32_round(struct fixed32_32 v)
-+{
-+ ASSERT(v.value + (1ULL<<31) >= (1ULL<<31));
-+ return (v.value + (1ULL<<31))>>32;
-+}
-+
-+bool dal_fixed32_32_eq(struct fixed32_32 lhs, struct fixed32_32 rhs)
-+{
-+ return lhs.value == rhs.value;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/basics/grph_object_id.c b/drivers/gpu/drm/amd/dal/dc/basics/grph_object_id.c
-new file mode 100644
-index 0000000..8276f9d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/basics/grph_object_id.c
-@@ -0,0 +1,135 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "include/grph_object_id.h"
-+
-+bool dal_graphics_object_id_is_valid(struct graphics_object_id id)
-+{
-+ bool rc = true;
-+
-+ switch (id.type) {
-+ case OBJECT_TYPE_UNKNOWN:
-+ rc = false;
-+ break;
-+ case OBJECT_TYPE_GPU:
-+ case OBJECT_TYPE_ENGINE:
-+ /* do NOT check for id.id == 0 */
-+ if (id.enum_id == ENUM_ID_UNKNOWN)
-+ rc = false;
-+ break;
-+ default:
-+ if (id.id == 0 || id.enum_id == ENUM_ID_UNKNOWN)
-+ rc = false;
-+ break;
-+ }
-+
-+ return rc;
-+}
-+
-+bool dal_graphics_object_id_is_equal(
-+ struct graphics_object_id id1,
-+ struct graphics_object_id id2)
-+{
-+ if (false == dal_graphics_object_id_is_valid(id1)) {
-+ dal_output_to_console(
-+ "%s: Warning: comparing invalid object 'id1'!\n", __func__);
-+ return false;
-+ }
-+
-+ if (false == dal_graphics_object_id_is_valid(id2)) {
-+ dal_output_to_console(
-+ "%s: Warning: comparing invalid object 'id2'!\n", __func__);
-+ return false;
-+ }
-+
-+ if (id1.id == id2.id && id1.enum_id == id2.enum_id
-+ && id1.type == id2.type)
-+ return true;
-+
-+ return false;
-+}
-+
-+/* Based on internal data members memory layout */
-+uint32_t dal_graphics_object_id_to_uint(struct graphics_object_id id)
-+{
-+ uint32_t object_id = 0;
-+
-+ object_id = id.id + (id.enum_id << 0x8) + (id.type << 0xc);
-+ return object_id;
-+}
-+
-+/*
-+ * ******* get specific ID - internal safe cast into specific type *******
-+ */
-+
-+enum controller_id dal_graphics_object_id_get_controller_id(
-+ struct graphics_object_id id)
-+{
-+ if (id.type == OBJECT_TYPE_CONTROLLER)
-+ return id.id;
-+ return CONTROLLER_ID_UNDEFINED;
-+}
-+
-+enum clock_source_id dal_graphics_object_id_get_clock_source_id(
-+ struct graphics_object_id id)
-+{
-+ if (id.type == OBJECT_TYPE_CLOCK_SOURCE)
-+ return id.id;
-+ return CLOCK_SOURCE_ID_UNDEFINED;
-+}
-+
-+enum encoder_id dal_graphics_object_id_get_encoder_id(
-+ struct graphics_object_id id)
-+{
-+ if (id.type == OBJECT_TYPE_ENCODER)
-+ return id.id;
-+ return ENCODER_ID_UNKNOWN;
-+}
-+
-+enum connector_id dal_graphics_object_id_get_connector_id(
-+ struct graphics_object_id id)
-+{
-+ if (id.type == OBJECT_TYPE_CONNECTOR)
-+ return id.id;
-+ return CONNECTOR_ID_UNKNOWN;
-+}
-+
-+enum audio_id dal_graphics_object_id_get_audio_id(struct graphics_object_id id)
-+{
-+ if (id.type == OBJECT_TYPE_AUDIO)
-+ return id.id;
-+ return AUDIO_ID_UNKNOWN;
-+}
-+
-+enum engine_id dal_graphics_object_id_get_engine_id(
-+ struct graphics_object_id id)
-+{
-+ if (id.type == OBJECT_TYPE_ENGINE)
-+ return id.id;
-+ return ENGINE_ID_UNKNOWN;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/basics/logger.c b/drivers/gpu/drm/amd/dal/dc/basics/logger.c
-new file mode 100644
-index 0000000..50db743
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/basics/logger.c
-@@ -0,0 +1,947 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#include <stdarg.h>
-+#include "dal_services.h"
-+#include "include/dal_types.h"
-+#include "include/logger_interface.h"
-+#include "logger.h"
-+
-+/* TODO: for now - empty, use DRM defines from dal services.
-+ Need to define appropriate levels of prints, and implement
-+ this component
-+void dal_log(const char *format, ...)
-+{
-+}
-+*/
-+
-+/* ----------- Logging Major/Minor names ------------ */
-+
-+#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
-+
-+static const struct log_minor_info component_minor_info_tbl[] = {
-+ {LOG_MINOR_COMPONENT_LINK_SERVICE, "LS"},
-+ {LOG_MINOR_COMPONENT_DAL_INTERFACE, "DalIf"},
-+ {LOG_MINOR_COMPONENT_HWSS, "HWSS"},
-+ {LOG_MINOR_COMPONENT_ADAPTER_SERVICE, "AS"},
-+ {LOG_MINOR_COMPONENT_DISPLAY_SERVICE, "DS"},
-+ {LOG_MINOR_COMPONENT_TOPOLOGY_MANAGER, "TM"},
-+ {LOG_MINOR_COMPONENT_ENCODER, "Encoder"},
-+ {LOG_MINOR_COMPONENT_I2C_AUX, "I2cAux"},
-+ {LOG_MINOR_COMPONENT_AUDIO, "Audio"},
-+ {LOG_MINOR_COMPONENT_DISPLAY_CAPABILITY_SERVICE, "Dcs"},
-+ {LOG_MINOR_COMPONENT_DMCU, "Dmcu"},
-+ {LOG_MINOR_COMPONENT_GPU, "GPU"},
-+ {LOG_MINOR_COMPONENT_CONTROLLER, "Cntrlr"},
-+ {LOG_MINOR_COMPONENT_ISR, "ISR"},
-+ {LOG_MINOR_COMPONENT_BIOS, "BIOS"},
-+ {LOG_MINOR_COMPONENT_DC, "DC"},
-+ {LOG_MINOR_COMPONENT_IRQ_SERVICE, "IRQ SERVICE"},
-+
-+};
-+
-+static const struct log_minor_info hw_trace_minor_info_tbl[] = {
-+ {LOG_MINOR_HW_TRACE_MST, "Mst" },
-+ {LOG_MINOR_HW_TRACE_TRAVIS, "Travis" },
-+ {LOG_MINOR_HW_TRACE_HOTPLUG, "Hotplug" },
-+ {LOG_MINOR_HW_TRACE_LINK_TRAINING, "LinkTraining" },
-+ {LOG_MINOR_HW_TRACE_SET_MODE, "SetMode" },
-+ {LOG_MINOR_HW_TRACE_RESUME_S3, "ResumeS3" },
-+ {LOG_MINOR_HW_TRACE_RESUME_S4, "ResumeS4" },
-+ {LOG_MINOR_HW_TRACE_BOOTUP, "BootUp" },
-+ {LOG_MINOR_HW_TRACE_AUDIO, "Audio"},
-+ {LOG_MINOR_HW_TRACE_HPD_IRQ, "HpdIrq" },
-+ {LOG_MINOR_HW_TRACE_INTERRUPT, "Interrupt" },
-+ {LOG_MINOR_HW_TRACE_MPO, "Planes" },
-+};
-+
-+static const struct log_minor_info mst_minor_info_tbl[] = {
-+ {LOG_MINOR_MST_IRQ_HPD_RX, "IrqHpdRx"},
-+ {LOG_MINOR_MST_IRQ_TIMER, "IrqTimer"},
-+ {LOG_MINOR_MST_NATIVE_AUX, "NativeAux"},
-+ {LOG_MINOR_MST_SIDEBAND_MSG, "SB"},
-+ {LOG_MINOR_MST_MSG_TRANSACTION, "MT"},
-+ {LOG_MINOR_MST_SIDEBAND_MSG_PARSED, "SB Parsed"},
-+ {LOG_MINOR_MST_MSG_TRANSACTION_PARSED, "MT Parsed"},
-+ {LOG_MINOR_MST_AUX_MSG_DPCD_ACCESS, "AuxMsgDpcdAccess"},
-+ {LOG_MINOR_MST_PROGRAMMING, "Programming"},
-+ {LOG_MINOR_MST_TOPOLOGY_DISCOVERY, "TopologyDiscovery"},
-+ {LOG_MINOR_MST_CONVERTER_CAPS, "ConverterCaps"},
-+};
-+
-+static const struct log_minor_info dcs_minor_info_tbl[] = {
-+ {LOG_MINOR_DCS_EDID_EMULATOR, "EdidEmul"},
-+ {LOG_MINOR_DCS_DONGLE_DETECTION, "DongleDetect"},
-+};
-+
-+static const struct log_minor_info dcp_minor_info_tbl[] = {
-+ { LOG_MINOR_DCP_GAMMA_GRPH, "GammaGrph"},
-+ { LOG_MINOR_DCP_GAMMA_OVL, "GammaOvl"},
-+ { LOG_MINOR_DCP_CSC_GRPH, "CscGrph"},
-+ { LOG_MINOR_DCP_CSC_OVL, "CscOvl"},
-+ { LOG_MINOR_DCP_SCALER, "Scaler"},
-+ { LOG_MINOR_DCP_SCALER_TABLES, "ScalerTables"},
-+};
-+
-+static const struct log_minor_info bios_minor_info_tbl[] = {
-+ {LOG_MINOR_BIOS_CMD_TABLE, "CmdTbl"},
-+};
-+
-+static const struct log_minor_info reg_minor_info_tbl[] = {
-+ {LOG_MINOR_REGISTER_INDEX, "Index"},
-+};
-+
-+static const struct log_minor_info info_packet_minor_info_tbl[] = {
-+ {LOG_MINOR_INFO_PACKETS_HDMI, "Hdmi"},
-+};
-+
-+
-+static const struct log_minor_info dsat_minor_info_tbl[] = {
-+ {LOG_MINOR_DSAT_LOGGER, "Logger"},
-+ {LOG_MINOR_DSAT_EDID_OVERRIDE, "EDID_Override"},
-+};
-+
-+static const struct log_minor_info ec_minor_info_tbl[] = {
-+ {LOG_MINOR_EC_PPLIB_NOTIFY, "PPLib_Notify" }, /* PPLib notifies DAL */
-+ {LOG_MINOR_EC_PPLIB_QUERY, "PPLib_Query" } /* DAL requested info from
-+ PPLib */
-+};
-+
-+static const struct log_minor_info bwm_minor_info_tbl[] = {
-+ {LOG_MINOR_BWM_MODE_VALIDATION, "ModeValidation"},
-+ {LOG_MINOR_BWM_REQUIRED_BANDWIDTH_CALCS, "Req_Bandw_Calcs"}
-+};
-+
-+static const struct log_minor_info mode_enum_minor_info_tbl[] = {
-+ {LOG_MINOR_MODE_ENUM_BEST_VIEW_CANDIDATES, "BestviewCandidates"},
-+ {LOG_MINOR_MODE_ENUM_VIEW_SOLUTION, "ViewSolution"},
-+ {LOG_MINOR_MODE_ENUM_TS_LIST_BUILD, "TsListBuild"},
-+ {LOG_MINOR_MODE_ENUM_TS_LIST, "TsList"},
-+ {LOG_MINOR_MODE_ENUM_MASTER_VIEW_LIST, "MasterViewList"},
-+ {LOG_MINOR_MODE_ENUM_MASTER_VIEW_LIST_UPDATE, "MasterViewListUpdate"},
-+};
-+
-+static const struct log_minor_info i2caux_minor_info_tbl[] = {
-+ {LOG_MINOR_I2C_AUX_LOG, "Log"},
-+ {LOG_MINOR_I2C_AUX_AUX_TIMESTAMP, "Timestamp"},
-+ {LOG_MINOR_I2C_AUX_CFG, "Config"}
-+};
-+
-+static const struct log_minor_info line_buffer_minor_info_tbl[] = {
-+ {LOG_MINOR_LINE_BUFFER_POWERGATING, "PowerGating"}
-+};
-+
-+static const struct log_minor_info hwss_minor_info_tbl[] = {
-+ {LOG_MINOR_HWSS_TAPS_VALIDATION, "HWSS Taps"}
-+};
-+
-+static const struct log_minor_info optimization_minor_info_tbl[] = {
-+ {LOG_MINOR_OPTMZ_GENERAL, "General Optimizations"},
-+ {LOG_MINOR_OPTMZ_DO_NOT_TURN_OFF_VCC_DURING_SET_MODE,
-+ "Skip Vcc Off During Set Mode"}
-+};
-+
-+static const struct log_minor_info perf_measure_minor_info_tbl[] = {
-+ {LOG_MINOR_PERF_MEASURE_GENERAL, "General Performance Measurement"},
-+ {LOG_MINOR_PERF_MEASURE_HEAP_MEMORY, "Heap Memory Management"}
-+};
-+
-+static const struct log_minor_info sync_minor_info_tbl[] = {
-+ {LOG_MINOR_SYNC_HW_CLOCK_ADJUST, "Pixel Rate Tune-up"},
-+ {LOG_MINOR_SYNC_TIMING, "Timing"}
-+};
-+
-+static const struct log_minor_info backlight_minor_info_tbl[] = {
-+ {LOG_MINOR_BACKLIGHT_BRIGHTESS_CAPS, "Caps"},
-+ {LOG_MINOR_BACKLIGHT_DMCU_DELTALUT, "DMCU Delta LUT"},
-+ {LOG_MINOR_BACKLIGHT_DMCU_BUILD_DELTALUT, "Build DMCU Delta LUT"},
-+ {LOG_MINOR_BACKLIGHT_INTERFACE, "Interface"},
-+ {LOG_MINOR_BACKLIGHT_LID, "Lid Status"}
-+};
-+
-+
-+static const struct log_minor_info override_feature_minor_info_tbl[] = {
-+ {LOG_MINOR_FEATURE_OVERRIDE, "overriden feature"},
-+};
-+
-+static const struct log_minor_info detection_minor_info_tbl[] = {
-+ {LOG_MINOR_DETECTION_EDID_PARSER, "EDID Parser"},
-+ {LOG_MINOR_DETECTION_DP_CAPS, "DP caps"},
-+};
-+
-+static const struct log_minor_info tm_minor_info_tbl[] = {
-+ {LOG_MINOR_TM_INFO, "INFO"},
-+ {LOG_MINOR_TM_IFACE_TRACE, "IFACE_TRACE"},
-+ {LOG_MINOR_TM_RESOURCES, "RESOURCES"},
-+ {LOG_MINOR_TM_ENCODER_CTL, "ENCODER_CTL"},
-+ {LOG_MINOR_TM_ENG_ASN, "ENG_ASN"},
-+ {LOG_MINOR_TM_CONTROLLER_ASN, "CONTROLLER_ASN"},
-+ {LOG_MINOR_TM_PWR_GATING, "PWR_GATING"},
-+ {LOG_MINOR_TM_BUILD_DSP_PATH, "BUILD_PATH"},
-+ {LOG_MINOR_TM_DISPLAY_DETECT, "DISPLAY_DETECT"},
-+ {LOG_MINOR_TM_LINK_SRV, "LINK_SRV"},
-+ {LOG_MINOR_TM_NOT_IMPLEMENTED, "NOT_IMPL"},
-+ {LOG_MINOR_TM_COFUNC_PATH, "COFUNC_PATH"}
-+};
-+
-+static const struct log_minor_info ds_minor_info_tbl[] = {
-+ {LOG_MINOR_DS_MODE_SETTING, "Mode_Setting"},
-+};
-+
-+
-+struct log_major_mask_info {
-+ struct log_major_info major_info;
-+ uint32_t default_mask;
-+ const struct log_minor_info *minor_tbl;
-+ uint32_t tbl_element_cnt;
-+};
-+
-+/* A mask for each Major.
-+ * Use a mask or zero. */
-+#define LG_ERR_MSK 0xffffffff
-+#define LG_WRN_MSK 0xffffffff
-+#define LG_TM_MSK (1 << LOG_MINOR_TM_INFO)
-+#define LG_FO_MSK (1 << LOG_MINOR_FEATURE_OVERRIDE)
-+#define LG_EC_MSK ((1 << LOG_MINOR_EC_PPLIB_NOTIFY) | \
-+ (1 << LOG_MINOR_EC_PPLIB_QUERY))
-+#define LG_DSAT_MSK (1 << LOG_MINOR_DSAT_EDID_OVERRIDE)
-+#define LG_DT_MSK (1 << LOG_MINOR_DETECTION_EDID_PARSER)
-+
-+/* IFT - InterFaceTrace */
-+#define LG_IFT_MSK (1 << LOG_MINOR_COMPONENT_DC)
-+
-+
-+#define LG_HW_TR_AUD_MSK (1 << LOG_MINOR_HW_TRACE_AUDIO)
-+#define LG_HW_TR_INTERRUPT_MSK (1 << LOG_MINOR_HW_TRACE_INTERRUPT) | \
-+ (1 << LOG_MINOR_HW_TRACE_HPD_IRQ)
-+#define LG_HW_TR_PLANES_MSK (1 << LOG_MINOR_HW_TRACE_MPO)
-+#define LG_ALL_MSK 0xffffffff
-+
-+#define LG_SYNC_MSK (1 << LOG_MINOR_SYNC_TIMING)
-+
-+#define LG_BWM_MSK (1 << LOG_MINOR_BWM_MODE_VALIDATION)
-+
-+
-+static const struct log_major_mask_info log_major_mask_info_tbl[] = {
-+ /* LogMajor major name default MinorTble tblElementCnt */
-+ {{LOG_MAJOR_ERROR, "Error" }, LG_ALL_MSK, component_minor_info_tbl, NUM_ELEMENTS(component_minor_info_tbl)},
-+ {{LOG_MAJOR_WARNING, "Warning" }, LG_ALL_MSK, component_minor_info_tbl, NUM_ELEMENTS(component_minor_info_tbl)},
-+ {{LOG_MAJOR_INTERFACE_TRACE, "IfTrace" }, LG_ALL_MSK, component_minor_info_tbl, NUM_ELEMENTS(component_minor_info_tbl)},
-+ {{LOG_MAJOR_HW_TRACE, "HwTrace" }, (LG_ALL_MSK &
-+ ~((1 << LOG_MINOR_HW_TRACE_LINK_TRAINING) |
-+ (1 << LOG_MINOR_HW_TRACE_AUDIO))),
-+ hw_trace_minor_info_tbl, NUM_ELEMENTS(hw_trace_minor_info_tbl)},
-+ {{LOG_MAJOR_MST, "MST" }, LG_ALL_MSK, mst_minor_info_tbl, NUM_ELEMENTS(mst_minor_info_tbl)},
-+ {{LOG_MAJOR_DCS, "DCS" }, LG_ALL_MSK, dcs_minor_info_tbl, NUM_ELEMENTS(dcs_minor_info_tbl)},
-+ {{LOG_MAJOR_DCP, "DCP" }, LG_ALL_MSK, dcp_minor_info_tbl, NUM_ELEMENTS(dcp_minor_info_tbl)},
-+ {{LOG_MAJOR_BIOS, "Bios" }, LG_ALL_MSK, bios_minor_info_tbl, NUM_ELEMENTS(bios_minor_info_tbl)},
-+ {{LOG_MAJOR_REGISTER, "Register" }, LG_ALL_MSK, reg_minor_info_tbl, NUM_ELEMENTS(reg_minor_info_tbl)},
-+ {{LOG_MAJOR_INFO_PACKETS, "InfoPacket" }, LG_ALL_MSK, info_packet_minor_info_tbl, NUM_ELEMENTS(info_packet_minor_info_tbl)},
-+ {{LOG_MAJOR_DSAT, "DSAT" }, LG_ALL_MSK, dsat_minor_info_tbl, NUM_ELEMENTS(dsat_minor_info_tbl)},
-+ {{LOG_MAJOR_EC, "EC" }, LG_ALL_MSK, ec_minor_info_tbl, NUM_ELEMENTS(ec_minor_info_tbl)},
-+ {{LOG_MAJOR_BWM, "BWM" }, LG_BWM_MSK, bwm_minor_info_tbl, NUM_ELEMENTS(bwm_minor_info_tbl)},
-+ {{LOG_MAJOR_MODE_ENUM, "ModeEnum" }, LG_ALL_MSK, mode_enum_minor_info_tbl, NUM_ELEMENTS(mode_enum_minor_info_tbl)},
-+ {{LOG_MAJOR_I2C_AUX, "I2cAux" }, LG_ALL_MSK, i2caux_minor_info_tbl, NUM_ELEMENTS(i2caux_minor_info_tbl)},
-+ {{LOG_MAJOR_LINE_BUFFER, "LineBuffer" }, LG_ALL_MSK, line_buffer_minor_info_tbl, NUM_ELEMENTS(line_buffer_minor_info_tbl)},
-+ {{LOG_MAJOR_HWSS, "HWSS" }, LG_ALL_MSK, hwss_minor_info_tbl, NUM_ELEMENTS(hwss_minor_info_tbl)},
-+ {{LOG_MAJOR_OPTIMIZATION, "Optimization"}, LG_ALL_MSK, optimization_minor_info_tbl, NUM_ELEMENTS(optimization_minor_info_tbl)},
-+ {{LOG_MAJOR_PERF_MEASURE, "PerfMeasure" }, LG_ALL_MSK, perf_measure_minor_info_tbl, NUM_ELEMENTS(perf_measure_minor_info_tbl)},
-+ {{LOG_MAJOR_SYNC, "Sync" }, LG_SYNC_MSK,sync_minor_info_tbl, NUM_ELEMENTS(sync_minor_info_tbl)},
-+ {{LOG_MAJOR_BACKLIGHT, "Backlight" }, LG_ALL_MSK, backlight_minor_info_tbl, NUM_ELEMENTS(backlight_minor_info_tbl)},
-+ {{LOG_MAJOR_INTERRUPTS, "Interrupts" }, LG_ALL_MSK, component_minor_info_tbl, NUM_ELEMENTS(component_minor_info_tbl)},
-+ {{LOG_MAJOR_TM, "TM" }, 0, tm_minor_info_tbl, NUM_ELEMENTS(tm_minor_info_tbl)},
-+ {{LOG_MAJOR_DISPLAY_SERVICE, "DS" }, LG_ALL_MSK, ds_minor_info_tbl, NUM_ELEMENTS(ds_minor_info_tbl)},
-+ {{LOG_MAJOR_FEATURE_OVERRIDE, "FeatureOverride" }, LG_ALL_MSK, override_feature_minor_info_tbl, NUM_ELEMENTS(override_feature_minor_info_tbl)},
-+ {{LOG_MAJOR_DETECTION, "Detection" }, LG_ALL_MSK, detection_minor_info_tbl, NUM_ELEMENTS(detection_minor_info_tbl)},
-+};
-+
-+/* ----------- Object init and destruction ----------- */
-+static bool construct(struct dc_context *ctx, struct dal_logger *logger)
-+{
-+ uint32_t i;
-+ /* malloc buffer and init offsets */
-+
-+ logger->log_buffer_size = DAL_LOGGER_BUFFER_MAX_SIZE;
-+ logger->log_buffer = (char *)dc_service_alloc(ctx,
-+ logger->log_buffer_size *
-+ sizeof(char));
-+
-+ if (!logger->log_buffer)
-+ return false;
-+
-+ /* todo: Fill buffer with \0 if not done by dal_alloc */
-+
-+ /* Initialize both offsets to start of buffer (empty) */
-+ logger->buffer_read_offset = 0;
-+ logger->buffer_write_offset = 0;
-+
-+ logger->write_wrap_count = 0;
-+ logger->read_wrap_count = 0;
-+ logger->open_count = 0;
-+
-+ logger->flags.bits.ENABLE_CONSOLE = 1;
-+ logger->flags.bits.ENABLE_BUFFER = 0;
-+
-+ logger->ctx = ctx;
-+
-+ /* malloc and init minor mask array */
-+ logger->log_enable_mask_minors =
-+ (uint32_t *)dc_service_alloc(
-+ ctx,
-+ NUM_ELEMENTS(log_major_mask_info_tbl)
-+ * sizeof(uint32_t));
-+ if (!logger->log_enable_mask_minors)
-+ return false;
-+
-+
-+ /* Set default values for mask */
-+ for (i = 0; i < NUM_ELEMENTS(log_major_mask_info_tbl); i++) {
-+
-+ uint32_t dflt_mask = log_major_mask_info_tbl[i].default_mask;
-+
-+ logger->log_enable_mask_minors[i] = dflt_mask;
-+ }
-+
-+ return true;
-+}
-+
-+static void destruct(struct dal_logger *logger)
-+{
-+ if (logger->log_buffer) {
-+ dc_service_free(logger->ctx, logger->log_buffer);
-+ logger->log_buffer = NULL;
-+ }
-+
-+ if (logger->log_enable_mask_minors) {
-+ dc_service_free(logger->ctx, logger->log_enable_mask_minors);
-+ logger->log_enable_mask_minors = NULL;
-+ }
-+}
-+
-+struct dal_logger *dal_logger_create(struct dc_context *ctx)
-+{
-+ /* malloc struct */
-+ struct dal_logger *logger = dc_service_alloc(ctx, sizeof(struct dal_logger));
-+
-+ if (!logger)
-+ return NULL;
-+ if (!construct(ctx, logger)) {
-+ dc_service_free(ctx, logger);
-+ return NULL;
-+ }
-+
-+ return logger;
-+}
-+
-+uint32_t dal_logger_destroy(struct dal_logger **logger)
-+{
-+ if (logger == NULL || *logger == NULL)
-+ return 1;
-+ destruct(*logger);
-+ dc_service_free((*logger)->ctx, *logger);
-+ *logger = NULL;
-+
-+ return 0;
-+}
-+
-+/* ------------------------------------------------------------------------ */
-+
-+static void lock(struct dal_logger *logger)
-+{
-+ /* Todo: lock mutex? */
-+}
-+
-+static void unlock(struct dal_logger *logger)
-+{
-+ /* Todo: unlock mutex */
-+}
-+
-+bool dal_logger_should_log(
-+ struct dal_logger *logger,
-+ enum log_major major,
-+ enum log_minor minor)
-+{
-+ if (major < LOG_MAJOR_COUNT) {
-+
-+ uint32_t minor_mask = logger->log_enable_mask_minors[major];
-+
-+ if ((minor_mask & (1 << minor)) != 0)
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+static void log_to_debug_console(struct log_entry *entry)
-+{
-+ struct dal_logger *logger = entry->logger;
-+
-+ if (logger->flags.bits.ENABLE_CONSOLE == 0)
-+ return;
-+
-+ switch (entry->major) {
-+ case LOG_MAJOR_ERROR:
-+ dal_error("%s", entry->buf);
-+ break;
-+ default:
-+ dal_output_to_console("%s", entry->buf);
-+ break;
-+ }
-+}
-+
-+/* Print everything unread existing in log_buffer to debug console*/
-+static void flush_to_debug_console(struct dal_logger *logger)
-+{
-+ int i = logger->buffer_read_offset;
-+ char *string_start = &logger->log_buffer[i];
-+
-+ dal_output_to_console(
-+ "---------------- FLUSHING LOG BUFFER ----------------\n");
-+ while (i < logger->buffer_write_offset) {
-+
-+ if (logger->log_buffer[i] == '\0') {
-+ dal_output_to_console("%s", string_start);
-+ string_start = (char *)logger->log_buffer + i + 1;
-+ }
-+ i++;
-+ }
-+ dal_output_to_console(
-+ "-------------- END FLUSHING LOG BUFFER --------------\n\n");
-+}
-+
-+static void log_to_internal_buffer(struct log_entry *entry)
-+{
-+
-+ uint32_t size = entry->buf_offset;
-+ struct dal_logger *logger = entry->logger;
-+
-+ if (logger->flags.bits.ENABLE_BUFFER == 0)
-+ return;
-+
-+ if (logger->log_buffer == NULL)
-+ return;
-+
-+ if (size > 0 && size < logger->log_buffer_size) {
-+
-+ int total_free_space = 0;
-+ int space_before_wrap = 0;
-+
-+ if (logger->buffer_write_offset > logger->buffer_read_offset) {
-+ total_free_space = logger->log_buffer_size -
-+ logger->buffer_write_offset +
-+ logger->buffer_read_offset;
-+ space_before_wrap = logger->log_buffer_size -
-+ logger->buffer_write_offset;
-+ } else if (logger->buffer_write_offset <
-+ logger->buffer_read_offset) {
-+ total_free_space = logger->log_buffer_size -
-+ logger->buffer_read_offset +
-+ logger->buffer_write_offset;
-+ space_before_wrap = total_free_space;
-+ } else if (logger->write_wrap_count !=
-+ logger->read_wrap_count) {
-+ /* Buffer is completely full already */
-+ total_free_space = 0;
-+ space_before_wrap = 0;
-+ } else {
-+ /* Buffer is empty, start writing at beginning */
-+ total_free_space = logger->log_buffer_size;
-+ space_before_wrap = logger->log_buffer_size;
-+ logger->buffer_write_offset = 0;
-+ logger->buffer_read_offset = 0;
-+ }
-+
-+
-+
-+
-+ if (space_before_wrap > size) {
-+ /* No wrap around, copy 'size' bytes
-+ * from 'entry->buf' to 'log_buffer'
-+ */
-+ dc_service_memmove(logger->log_buffer +
-+ logger->buffer_write_offset,
-+ entry->buf, size);
-+ logger->buffer_write_offset += size;
-+
-+ } else if (total_free_space > size) {
-+ /* We have enough room without flushing,
-+ * but need to wrap around */
-+
-+ int space_after_wrap = total_free_space -
-+ space_before_wrap;
-+
-+ dc_service_memmove(logger->log_buffer +
-+ logger->buffer_write_offset,
-+ entry->buf, space_before_wrap);
-+ dc_service_memmove(logger->log_buffer, entry->buf +
-+ space_before_wrap, space_after_wrap);
-+
-+ logger->buffer_write_offset = space_after_wrap;
-+ logger->write_wrap_count++;
-+
-+ } else {
-+ /* Not enough room remaining, we should flush
-+ * existing logs */
-+
-+ /* Flush existing unread logs to console */
-+ flush_to_debug_console(logger);
-+
-+ /* Start writing to beginning of buffer */
-+ dc_service_memmove(logger->log_buffer, entry->buf, size);
-+ logger->buffer_write_offset = size;
-+ logger->buffer_read_offset = 0;
-+ }
-+
-+ }
-+
-+ unlock(logger);
-+}
-+
-+
-+static void log_timestamp(struct log_entry *entry)
-+{
-+ dal_logger_append(entry, "00:00:00 ");
-+}
-+
-+static void log_major_minor(struct log_entry *entry)
-+{
-+ uint32_t i;
-+ enum log_major major = entry->major;
-+ enum log_minor minor = entry->minor;
-+
-+ for (i = 0; i < NUM_ELEMENTS(log_major_mask_info_tbl); i++) {
-+
-+ const struct log_major_mask_info *maj_mask_info =
-+ &log_major_mask_info_tbl[i];
-+
-+ if (maj_mask_info->major_info.major == major) {
-+
-+ dal_logger_append(entry, "[%s_",
-+ maj_mask_info->major_info.major_name);
-+
-+ if (maj_mask_info->minor_tbl != NULL) {
-+ uint32_t j;
-+
-+ for (j = 0; j < maj_mask_info->tbl_element_cnt; j++) {
-+
-+ const struct log_minor_info *min_info = &maj_mask_info->minor_tbl[j];
-+
-+ if (min_info->minor == minor)
-+ dal_logger_append(entry, "%s]\t", min_info->minor_name);
-+ }
-+ }
-+
-+ break;
-+ }
-+ }
-+}
-+
-+static void log_heading(struct log_entry *entry,
-+ enum log_major major,
-+ enum log_minor minor)
-+{
-+ log_timestamp(entry);
-+ log_major_minor(entry);
-+}
-+
-+
-+static void append_entry(
-+ struct log_entry *entry,
-+ char *buffer,
-+ uint32_t buf_size)
-+{
-+ if (!entry->buf ||
-+ entry->buf_offset + buf_size > entry->max_buf_bytes
-+ ) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ /* Todo: check if off by 1 byte due to \0 anywhere */
-+ dc_service_memmove(entry->buf + entry->buf_offset, buffer, buf_size);
-+ entry->buf_offset += buf_size;
-+}
-+
-+/* ------------------------------------------------------------------------ */
-+
-+/* Warning: Be careful that 'msg' is null terminated and the total size is
-+ * less than DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE (256) including '\0'
-+ */
-+void dal_logger_write(
-+ struct dal_logger *logger,
-+ enum log_major major,
-+ enum log_minor minor,
-+ const char *msg,
-+ ...)
-+{
-+
-+ if (logger && dal_logger_should_log(logger, major, minor)) {
-+
-+ uint32_t size;
-+ va_list args;
-+ char buffer[DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE];
-+ struct log_entry entry;
-+
-+ va_start(args, msg);
-+ dal_logger_open(logger, &entry, major, minor);
-+
-+
-+ size = dal_log_to_buffer(
-+ buffer, DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE, msg, args);
-+
-+ if (size > 0 && size <
-+ DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE - 1) {
-+
-+ if (buffer[size] == '\0')
-+ size++; /* Add one for null terminator */
-+
-+ /* Concatenate onto end of entry buffer */
-+ append_entry(&entry, buffer, size);
-+ } else {
-+ append_entry(&entry, "LOG_ERROR\n", 12);
-+ }
-+
-+ dal_logger_close(&entry);
-+ va_end(args);
-+
-+ }
-+}
-+
-+
-+/* Same as dal_logger_write, except without open() and close(), which must
-+ * be done separately.
-+ */
-+void dal_logger_append(
-+ struct log_entry *entry,
-+ const char *msg,
-+ ...)
-+{
-+ struct dal_logger *logger;
-+
-+ if (!entry) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ logger = entry->logger;
-+
-+ if (logger && logger->open_count > 0 &&
-+ dal_logger_should_log(logger, entry->major, entry->minor)) {
-+
-+ uint32_t size;
-+ va_list args;
-+ char buffer[DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE];
-+
-+ va_start(args, msg);
-+
-+ size = dal_log_to_buffer(
-+ buffer, DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE, msg, args);
-+ append_entry(entry, buffer, size);
-+
-+ va_end(args);
-+ }
-+}
-+
-+
-+uint32_t dal_logger_read(
-+ struct dal_logger *logger, /* <[in] */
-+ uint32_t output_buffer_size, /* <[in] */
-+ char *output_buffer, /* >[out] */
-+ uint32_t *bytes_read, /* >[out] */
-+ bool single_line)
-+{
-+ uint32_t bytes_remaining = 0;
-+ uint32_t bytes_read_count = 0;
-+ bool keep_reading = true;
-+
-+ if (!logger || output_buffer == NULL || output_buffer_size == 0) {
-+ BREAK_TO_DEBUGGER();
-+ *bytes_read = 0;
-+ return 0;
-+ }
-+
-+ lock(logger);
-+
-+ /* Read until null terminator (if single_line==true,
-+ * max buffer size, or until we've read everything new
-+ */
-+
-+ do {
-+ char cur;
-+
-+ /* Stop when we've read everything */
-+ if (logger->buffer_read_offset ==
-+ logger->buffer_write_offset) {
-+
-+ break;
-+ }
-+
-+ cur = logger->log_buffer[logger->buffer_read_offset];
-+ logger->buffer_read_offset++;
-+
-+ /* Wrap read pointer if at end */
-+ if (logger->buffer_read_offset == logger->log_buffer_size) {
-+
-+ logger->buffer_read_offset = 0;
-+ logger->read_wrap_count++;
-+ }
-+
-+ /* Don't send null terminators to buffer */
-+ if (cur != '\0') {
-+ output_buffer[bytes_read_count] = cur;
-+ bytes_read_count++;
-+ } else if (single_line) {
-+ keep_reading = false;
-+ }
-+
-+ } while (bytes_read_count <= output_buffer_size && keep_reading);
-+
-+ /* We assume that reading can never be ahead of writing */
-+ if (logger->write_wrap_count > logger->read_wrap_count) {
-+ bytes_remaining = logger->log_buffer_size -
-+ logger->buffer_read_offset +
-+ logger->buffer_write_offset;
-+ } else {
-+ bytes_remaining = logger->buffer_write_offset -
-+ logger->buffer_read_offset;
-+ }
-+
-+ /* reset write/read wrap count to 0 if we've read everything */
-+ if (bytes_remaining == 0) {
-+
-+ logger->write_wrap_count = 0;
-+ logger->read_wrap_count = 0;
-+ }
-+
-+ *bytes_read = bytes_read_count;
-+ unlock(logger);
-+
-+ return bytes_remaining;
-+}
-+
-+void dal_logger_open(
-+ struct dal_logger *logger,
-+ struct log_entry *entry, /* out */
-+ enum log_major major,
-+ enum log_minor minor)
-+{
-+ if (!entry) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ entry->major = LOG_MAJOR_COUNT;
-+ entry->minor = 0;
-+ entry->logger = logger;
-+
-+ entry->buf = dc_service_alloc(
-+ logger->ctx,
-+ DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE * sizeof(char));
-+
-+ entry->buf_offset = 0;
-+ entry->max_buf_bytes =
-+ DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE * sizeof(char);
-+
-+ logger->open_count++;
-+ entry->major = major;
-+ entry->minor = minor;
-+
-+ log_heading(entry, major, minor);
-+}
-+
-+void dal_logger_close(struct log_entry *entry)
-+{
-+ struct dal_logger *logger = entry->logger;
-+
-+
-+ if (logger && logger->open_count > 0) {
-+ logger->open_count--;
-+ } else {
-+ BREAK_TO_DEBUGGER();
-+ goto cleanup;
-+ }
-+
-+ /* --Flush log_entry buffer-- */
-+ /* print to kernel console */
-+ log_to_debug_console(entry);
-+ /* log internally for dsat */
-+ log_to_internal_buffer(entry);
-+
-+ /* TODO: Write end heading */
-+
-+cleanup:
-+ if (entry->buf) {
-+ dc_service_free(entry->logger->ctx, entry->buf);
-+ entry->buf = NULL;
-+ entry->buf_offset = 0;
-+ entry->max_buf_bytes = 0;
-+ }
-+}
-+
-+uint32_t dal_logger_get_mask(
-+ struct dal_logger *logger,
-+ enum log_major lvl_major, enum log_minor lvl_minor)
-+{
-+ uint32_t log_mask = 0;
-+
-+ if (logger && lvl_major < LOG_MAJOR_COUNT)
-+ log_mask = logger->log_enable_mask_minors[lvl_major];
-+
-+ log_mask &= 1 << lvl_minor;
-+ return log_mask;
-+}
-+
-+uint32_t dal_logger_set_mask(
-+ struct dal_logger *logger,
-+ enum log_major lvl_major, enum log_minor lvl_minor)
-+{
-+
-+ if (logger && lvl_major < LOG_MAJOR_COUNT) {
-+ if (lvl_minor == LOG_MINOR_MASK_ALL) {
-+ logger->log_enable_mask_minors[lvl_major] = 0xFFFFFFFF;
-+ } else {
-+ logger->log_enable_mask_minors[lvl_major] |=
-+ (1 << lvl_minor);
-+ }
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+uint32_t dal_logger_get_masks(
-+ struct dal_logger *logger,
-+ enum log_major lvl_major)
-+{
-+ uint32_t log_mask = 0;
-+
-+ if (logger && lvl_major < LOG_MAJOR_COUNT)
-+ log_mask = logger->log_enable_mask_minors[lvl_major];
-+
-+ return log_mask;
-+}
-+
-+void dal_logger_set_masks(
-+ struct dal_logger *logger,
-+ enum log_major lvl_major, uint32_t log_mask)
-+{
-+ if (logger && lvl_major < LOG_MAJOR_COUNT)
-+ logger->log_enable_mask_minors[lvl_major] = log_mask;
-+}
-+
-+uint32_t dal_logger_unset_mask(
-+ struct dal_logger *logger,
-+ enum log_major lvl_major, enum log_minor lvl_minor)
-+{
-+
-+ if (lvl_major < LOG_MAJOR_COUNT) {
-+ if (lvl_minor == LOG_MINOR_MASK_ALL) {
-+ logger->log_enable_mask_minors[lvl_major] = 0;
-+ } else {
-+ logger->log_enable_mask_minors[lvl_major] &=
-+ ~(1 << lvl_minor);
-+ }
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+uint32_t dal_logger_get_flags(
-+ struct dal_logger *logger)
-+{
-+
-+ return logger->flags.value;
-+}
-+
-+void dal_logger_set_flags(
-+ struct dal_logger *logger,
-+ union logger_flags flags)
-+{
-+
-+ logger->flags = flags;
-+}
-+
-+
-+uint32_t dal_logger_get_buffer_size(struct dal_logger *logger)
-+{
-+ return DAL_LOGGER_BUFFER_MAX_SIZE;
-+}
-+
-+uint32_t dal_logger_set_buffer_size(
-+ struct dal_logger *logger,
-+ uint32_t new_size)
-+{
-+ /* ToDo: implement dynamic size */
-+
-+ /* return new size */
-+ return DAL_LOGGER_BUFFER_MAX_SIZE;
-+}
-+
-+
-+const struct log_major_info *dal_logger_enum_log_major_info(
-+ struct dal_logger *logger,
-+ unsigned int enum_index)
-+{
-+ const struct log_major_info *major_info;
-+
-+ if (enum_index >= NUM_ELEMENTS(log_major_mask_info_tbl))
-+ return NULL;
-+
-+ major_info = &log_major_mask_info_tbl[enum_index].major_info;
-+ return major_info;
-+}
-+
-+const struct log_minor_info *dal_logger_enum_log_minor_info(
-+ struct dal_logger *logger,
-+ enum log_major major,
-+ unsigned int enum_index)
-+{
-+ const struct log_minor_info *minor_info = NULL;
-+ uint32_t i;
-+
-+ for (i = 0; i < NUM_ELEMENTS(log_major_mask_info_tbl); i++) {
-+
-+ const struct log_major_mask_info *maj_mask_info =
-+ &log_major_mask_info_tbl[i];
-+
-+ if (maj_mask_info->major_info.major == major) {
-+
-+ if (maj_mask_info->minor_tbl != NULL) {
-+ uint32_t j;
-+
-+ for (j = 0; j < maj_mask_info->tbl_element_cnt; j++) {
-+
-+ minor_info = &maj_mask_info->minor_tbl[j];
-+
-+ if (minor_info->minor == enum_index)
-+ return minor_info;
-+ }
-+ }
-+
-+ break;
-+ }
-+ }
-+ return NULL;
-+
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/basics/logger.h b/drivers/gpu/drm/amd/dal/dc/basics/logger.h
-new file mode 100644
-index 0000000..fba5ec3
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/basics/logger.h
-@@ -0,0 +1,64 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_LOGGER_H__
-+#define __DAL_LOGGER_H__
-+
-+/* Structure for keeping track of offsets, buffer, etc */
-+
-+#define DAL_LOGGER_BUFFER_MAX_SIZE 2048
-+#define DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE 256
-+
-+
-+#include "include/logger_types.h"
-+
-+struct dal_logger {
-+
-+ /* How far into the circular buffer has been read by dsat
-+ * Read offset should never cross write offset. Write \0's to
-+ * read data just to be sure?
-+ */
-+ uint32_t buffer_read_offset;
-+
-+ /* How far into the circular buffer we have written
-+ * Write offset should never cross read offset
-+ */
-+ uint32_t buffer_write_offset;
-+
-+ uint32_t write_wrap_count;
-+ uint32_t read_wrap_count;
-+
-+ uint32_t open_count;
-+
-+ char *log_buffer; /* Pointer to malloc'ed buffer */
-+ uint32_t log_buffer_size; /* Size of circular buffer */
-+
-+ uint32_t *log_enable_mask_minors; /*array of masks for major elements*/
-+
-+ union logger_flags flags;
-+ struct dc_context *ctx;
-+};
-+
-+#endif /* __DAL_LOGGER_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/basics/register_logger.c b/drivers/gpu/drm/amd/dal/dc/basics/register_logger.c
-new file mode 100644
-index 0000000..a3086a0
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/basics/register_logger.c
-@@ -0,0 +1,197 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/dal_types.h"
-+#include "include/logger_interface.h"
-+#include "logger.h"
-+
-+/******************************************************************************
-+ * Register Logger.
-+ * A facility to create register R/W logs.
-+ * Currently used for DAL Test.
-+ *****************************************************************************/
-+
-+/******************************************************************************
-+ * Private structures
-+ *****************************************************************************/
-+struct dal_reg_dump_stack_location {
-+ const char *current_caller_func;
-+ long current_pid;
-+ long current_tgid;
-+ uint32_t rw_count;/* register access counter for current function. */
-+};
-+
-+/* This the maximum number of nested calls to the 'reg_dump' facility. */
-+#define DAL_REG_DUMP_STACK_MAX_SIZE 32
-+
-+struct dal_reg_dump_stack {
-+ int32_t stack_pointer;
-+ struct dal_reg_dump_stack_location
-+ stack_locations[DAL_REG_DUMP_STACK_MAX_SIZE];
-+ uint32_t total_rw_count; /* Total count for *all* functions. */
-+};
-+
-+static struct dal_reg_dump_stack reg_dump_stack = {0};
-+
-+/******************************************************************************
-+ * Private functions
-+ *****************************************************************************/
-+
-+/* Check if current process is the one which requested register dump.
-+ * The reason for the check:
-+ * mmCRTC_STATUS_FRAME_COUNT is accessed by dal_controller_get_vblank_counter().
-+ * Which runs all the time when at least one display is connected.
-+ * (Triggered by drm_mode_page_flip_ioctl()). */
-+static bool is_reg_dump_process(void)
-+{
-+ uint32_t i;
-+
-+ /* walk the list of our processes */
-+ for (i = 0; i < reg_dump_stack.stack_pointer; i++) {
-+ struct dal_reg_dump_stack_location *stack_location
-+ = &reg_dump_stack.stack_locations[i];
-+
-+ if (stack_location->current_pid == dal_get_pid()
-+ && stack_location->current_tgid == dal_get_tgid())
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+static bool dal_reg_dump_stack_is_empty(void)
-+{
-+ if (reg_dump_stack.stack_pointer <= 0)
-+ return true;
-+ else
-+ return false;
-+}
-+
-+static struct dal_reg_dump_stack_location *dal_reg_dump_stack_push(void)
-+{
-+ struct dal_reg_dump_stack_location *current_location = NULL;
-+
-+ if (reg_dump_stack.stack_pointer >= DAL_REG_DUMP_STACK_MAX_SIZE) {
-+ /* stack is full */
-+ dal_output_to_console("[REG_DUMP]: %s: stack is full!\n",
-+ __func__);
-+ } else {
-+ current_location =
-+ &reg_dump_stack.stack_locations[reg_dump_stack.stack_pointer];
-+ ++reg_dump_stack.stack_pointer;
-+ }
-+
-+ return current_location;
-+}
-+
-+static struct dal_reg_dump_stack_location *dal_reg_dump_stack_pop(void)
-+{
-+ struct dal_reg_dump_stack_location *current_location = NULL;
-+
-+ if (dal_reg_dump_stack_is_empty()) {
-+ /* stack is empty */
-+ dal_output_to_console("[REG_DUMP]: %s: stack is empty!\n",
-+ __func__);
-+ } else {
-+ --reg_dump_stack.stack_pointer;
-+ current_location =
-+ &reg_dump_stack.stack_locations[reg_dump_stack.stack_pointer];
-+ }
-+
-+ return current_location;
-+}
-+
-+/******************************************************************************
-+ * Public functions
-+ *****************************************************************************/
-+
-+void dal_reg_logger_push(const char *caller_func)
-+{
-+ struct dal_reg_dump_stack_location *free_stack_location;
-+
-+ free_stack_location = dal_reg_dump_stack_push();
-+
-+ if (NULL == free_stack_location)
-+ return;
-+
-+ dc_service_memset(free_stack_location, 0, sizeof(*free_stack_location));
-+
-+ free_stack_location->current_caller_func = caller_func;
-+ free_stack_location->current_pid = dal_get_pid();
-+ free_stack_location->current_tgid = dal_get_tgid();
-+
-+ dal_output_to_console("[REG_DUMP]:%s - start (pid:%ld, tgid:%ld)\n",
-+ caller_func,
-+ free_stack_location->current_pid,
-+ free_stack_location->current_tgid);
-+}
-+
-+void dal_reg_logger_pop(void)
-+{
-+ struct dal_reg_dump_stack_location *top_stack_location;
-+
-+ top_stack_location = dal_reg_dump_stack_pop();
-+
-+ if (NULL == top_stack_location) {
-+ dal_output_to_console("[REG_DUMP]:%s - Stack is Empty!\n",
-+ __func__);
-+ return;
-+ }
-+
-+ dal_output_to_console(
-+ "[REG_DUMP]:%s - end."\
-+ " Reg R/W Count: Total=%d Function=%d. (pid:%ld, tgid:%ld)\n",
-+ top_stack_location->current_caller_func,
-+ reg_dump_stack.total_rw_count,
-+ top_stack_location->rw_count,
-+ dal_get_pid(),
-+ dal_get_tgid());
-+
-+ dc_service_memset(top_stack_location, 0, sizeof(*top_stack_location));
-+}
-+
-+void dal_reg_logger_rw_count_increment(void)
-+{
-+ ++reg_dump_stack.total_rw_count;
-+
-+ ++reg_dump_stack.stack_locations
-+ [reg_dump_stack.stack_pointer - 1].rw_count;
-+}
-+
-+bool dal_reg_logger_should_dump_register(void)
-+{
-+ if (true == dal_reg_dump_stack_is_empty())
-+ return false;
-+
-+ if (false == is_reg_dump_process())
-+ return false;
-+
-+ return true;
-+}
-+
-+/******************************************************************************
-+ * End of File.
-+ *****************************************************************************/
-diff --git a/drivers/gpu/drm/amd/dal/dc/basics/signal_types.c b/drivers/gpu/drm/amd/dal/dc/basics/signal_types.c
-new file mode 100644
-index 0000000..f589091
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/basics/signal_types.c
-@@ -0,0 +1,116 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dc_services.h"
-+#include "include/signal_types.h"
-+
-+bool dc_is_hdmi_signal(enum signal_type signal)
-+{
-+ return (signal == SIGNAL_TYPE_HDMI_TYPE_A);
-+}
-+
-+bool dc_is_dp_sst_signal(enum signal_type signal)
-+{
-+ return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
-+ signal == SIGNAL_TYPE_EDP);
-+}
-+
-+bool dc_is_dp_signal(enum signal_type signal)
-+{
-+ return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
-+ signal == SIGNAL_TYPE_EDP ||
-+ signal == SIGNAL_TYPE_DISPLAY_PORT_MST);
-+}
-+
-+bool dc_is_dp_external_signal(enum signal_type signal)
-+{
-+ return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
-+ signal == SIGNAL_TYPE_DISPLAY_PORT_MST);
-+}
-+
-+bool dc_is_analog_signal(enum signal_type signal)
-+{
-+ switch (signal) {
-+ case SIGNAL_TYPE_RGB:
-+ return true;
-+ break;
-+ default:
-+ return false;
-+ }
-+}
-+
-+bool dc_is_embedded_signal(enum signal_type signal)
-+{
-+ return (signal == SIGNAL_TYPE_EDP || signal == SIGNAL_TYPE_LVDS);
-+}
-+
-+bool dc_is_dvi_signal(enum signal_type signal)
-+{
-+ switch (signal) {
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
-+ case SIGNAL_TYPE_DVI_DUAL_LINK:
-+ return true;
-+ break;
-+ default:
-+ return false;
-+ }
-+}
-+
-+bool dc_is_dvi_single_link_signal(enum signal_type signal)
-+{
-+ return (signal == SIGNAL_TYPE_DVI_SINGLE_LINK);
-+}
-+
-+bool dc_is_dual_link_signal(enum signal_type signal)
-+{
-+ return (signal == SIGNAL_TYPE_DVI_DUAL_LINK);
-+}
-+
-+bool dc_is_audio_capable_signal(enum signal_type signal)
-+{
-+ return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
-+ signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
-+ dc_is_hdmi_signal(signal) ||
-+ signal == SIGNAL_TYPE_WIRELESS);
-+}
-+
-+/*
-+ * @brief
-+ * Returns whether the signal is compatible
-+ * with other digital encoder signal types.
-+ * This is true for DVI, LVDS, and HDMI signal types.
-+ */
-+bool dc_is_digital_encoder_compatible_signal(enum signal_type signal)
-+{
-+ switch (signal) {
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
-+ case SIGNAL_TYPE_DVI_DUAL_LINK:
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ case SIGNAL_TYPE_LVDS:
-+ return true;
-+ default:
-+ return false;
-+ }
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/basics/vector.c b/drivers/gpu/drm/amd/dal/dc/basics/vector.c
-new file mode 100644
-index 0000000..2f932c0
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/basics/vector.c
-@@ -0,0 +1,309 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/vector.h"
-+
-+bool dal_vector_construct(
-+ struct vector *vector,
-+ struct dc_context *ctx,
-+ uint32_t capacity,
-+ uint32_t struct_size)
-+{
-+ vector->container = NULL;
-+
-+ if (!struct_size || !capacity) {
-+ /* Container must be non-zero size*/
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ vector->container = dc_service_alloc(ctx, struct_size * capacity);
-+ if (vector->container == NULL)
-+ return false;
-+ vector->capacity = capacity;
-+ vector->struct_size = struct_size;
-+ vector->count = 0;
-+ vector->ctx = ctx;
-+ return true;
-+}
-+
-+bool dal_vector_presized_costruct(
-+ struct vector *vector,
-+ struct dc_context *ctx,
-+ uint32_t count,
-+ void *initial_value,
-+ uint32_t struct_size)
-+{
-+ uint32_t i;
-+
-+ vector->container = NULL;
-+
-+ if (!struct_size || !count) {
-+ /* Container must be non-zero size*/
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ vector->container = dc_service_alloc(ctx, struct_size * count);
-+
-+ if (vector->container == NULL)
-+ return false;
-+
-+ /* If caller didn't supply initial value then the default
-+ * of all zeros is expected, which is exactly what dal_alloc()
-+ * initialises the memory to. */
-+ if (NULL != initial_value) {
-+ for (i = 0; i < count; ++i)
-+ dc_service_memmove(
-+ vector->container + i * struct_size,
-+ initial_value,
-+ struct_size);
-+ }
-+
-+ vector->capacity = count;
-+ vector->struct_size = struct_size;
-+ vector->count = count;
-+ return true;
-+}
-+
-+struct vector *dal_vector_presized_create(
-+ struct dc_context *ctx,
-+ uint32_t size,
-+ void *initial_value,
-+ uint32_t struct_size)
-+{
-+ struct vector *vector = dc_service_alloc(ctx, sizeof(struct vector));
-+
-+ if (vector == NULL)
-+ return NULL;
-+
-+ if (dal_vector_presized_costruct(
-+ vector, ctx, size, initial_value, struct_size))
-+ return vector;
-+
-+ BREAK_TO_DEBUGGER();
-+ dc_service_free(ctx, vector);
-+ return NULL;
-+}
-+
-+struct vector *dal_vector_create(
-+ struct dc_context *ctx,
-+ uint32_t capacity,
-+ uint32_t struct_size)
-+{
-+ struct vector *vector = dc_service_alloc(ctx, sizeof(struct vector));
-+
-+ if (vector == NULL)
-+ return NULL;
-+
-+ if (dal_vector_construct(vector, ctx, capacity, struct_size))
-+ return vector;
-+
-+
-+ BREAK_TO_DEBUGGER();
-+ dc_service_free(ctx, vector);
-+ return NULL;
-+}
-+
-+void dal_vector_destruct(
-+ struct vector *vector)
-+{
-+ if (vector->container != NULL)
-+ dc_service_free(vector->ctx, vector->container);
-+ vector->count = 0;
-+ vector->capacity = 0;
-+}
-+
-+void dal_vector_destroy(
-+ struct vector **vector)
-+{
-+ if (vector == NULL || *vector == NULL)
-+ return;
-+ dal_vector_destruct(*vector);
-+ dc_service_free((*vector)->ctx, *vector);
-+ *vector = NULL;
-+}
-+
-+uint32_t dal_vector_get_count(
-+ const struct vector *vector)
-+{
-+ return vector->count;
-+}
-+
-+void *dal_vector_at_index(
-+ const struct vector *vector,
-+ uint32_t index)
-+{
-+ if (vector->container == NULL || index >= vector->count)
-+ return NULL;
-+ return vector->container + (index * vector->struct_size);
-+}
-+
-+bool dal_vector_remove_at_index(
-+ struct vector *vector,
-+ uint32_t index)
-+{
-+ if (index >= vector->count)
-+ return false;
-+
-+ if (index != vector->count - 1)
-+ dc_service_memmove(
-+ vector->container + (index * vector->struct_size),
-+ vector->container + ((index + 1) * vector->struct_size),
-+ (vector->count - index - 1) * vector->struct_size);
-+ vector->count -= 1;
-+
-+ return true;
-+}
-+
-+void dal_vector_set_at_index(
-+ const struct vector *vector,
-+ const void *what,
-+ uint32_t index)
-+{
-+ void *where = dal_vector_at_index(vector, index);
-+
-+ if (!where) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+ dc_service_memmove(
-+ where,
-+ what,
-+ vector->struct_size);
-+}
-+
-+static inline uint32_t calc_increased_capacity(
-+ uint32_t old_capacity)
-+{
-+ return old_capacity * 2;
-+}
-+
-+bool dal_vector_insert_at(
-+ struct vector *vector,
-+ const void *what,
-+ uint32_t position)
-+{
-+ uint8_t *insert_address;
-+
-+ if (vector->count == vector->capacity) {
-+ if (!dal_vector_reserve(
-+ vector,
-+ calc_increased_capacity(vector->capacity)))
-+ return false;
-+ }
-+
-+ insert_address = vector->container + (vector->struct_size * position);
-+
-+ if (vector->count && position < vector->count)
-+ dc_service_memmove(
-+ insert_address + vector->struct_size,
-+ insert_address,
-+ vector->struct_size * (vector->count - position));
-+
-+ dc_service_memmove(
-+ insert_address,
-+ what,
-+ vector->struct_size);
-+
-+ vector->count++;
-+
-+ return true;
-+}
-+
-+bool dal_vector_append(
-+ struct vector *vector,
-+ const void *item)
-+{
-+ return dal_vector_insert_at(vector, item, vector->count);
-+}
-+
-+struct vector *dal_vector_clone(
-+ const struct vector *vector)
-+{
-+ struct vector *vec_cloned;
-+ uint32_t count;
-+
-+ /* create new vector */
-+ count = dal_vector_get_count(vector);
-+
-+ if (count == 0)
-+ /* when count is 0 we still want to create clone of the vector
-+ */
-+ vec_cloned = dal_vector_create(
-+ vector->ctx,
-+ vector->capacity,
-+ vector->struct_size);
-+ else
-+ /* Call "presized create" version, independently of how the
-+ * original vector was created.
-+ * The owner of original vector must know how to treat the new
-+ * vector - as "presized" or as "regular".
-+ * But from vector point of view it doesn't matter. */
-+ vec_cloned = dal_vector_presized_create(vector->ctx, count,
-+ NULL,/* no initial value */
-+ vector->struct_size);
-+
-+ if (NULL == vec_cloned) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ /* copy vector's data */
-+ dc_service_memmove(vec_cloned->container, vector->container,
-+ vec_cloned->struct_size * vec_cloned->capacity);
-+
-+ return vec_cloned;
-+}
-+
-+uint32_t dal_vector_capacity(const struct vector *vector)
-+{
-+ return vector->capacity;
-+}
-+
-+bool dal_vector_reserve(struct vector *vector, uint32_t capacity)
-+{
-+ void *new_container;
-+
-+ if (capacity <= vector->capacity)
-+ return true;
-+
-+ new_container = dc_service_realloc(vector->ctx, vector->container,
-+ capacity * vector->struct_size);
-+
-+ if (new_container) {
-+ vector->container = new_container;
-+ vector->capacity = capacity;
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+void dal_vector_clear(struct vector *vector)
-+{
-+ vector->count = 0;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/Makefile b/drivers/gpu/drm/amd/dal/dc/bios/Makefile
-new file mode 100644
-index 0000000..75bb892
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/Makefile
-@@ -0,0 +1,27 @@
-+#
-+# Makefile for the 'bios' sub-component of DAL.
-+# It provides the parsing and executing controls for atom bios image.
-+
-+BIOS = bios_parser.o bios_parser_helper.o command_table.o command_table_helper.o
-+
-+AMD_DAL_BIOS = $(addprefix $(AMDDALPATH)/dc/bios/,$(BIOS))
-+
-+AMD_DAL_FILES += $(AMD_DAL_BIOS)
-+
-+ifndef CONFIG_DRM_AMD_DAL_VBIOS_PRESENT
-+AMD_DAL_FILES := $(filter-out $(AMDDALPATH)/dc/bios/bios_parser_helper.o,$(AMD_DAL_FILES))
-+endif
-+$(warning AMD_DAL_FILES=$(AMD_DAL_FILES))
-+
-+
-+###############################################################################
-+# DCE 11x
-+###############################################################################
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_0
-+
-+ifdef CONFIG_DRM_AMD_DAL_VBIOS_PRESENT
-+AMD_DAL_FILES += $(AMDDALPATH)/dc/bios/dce110/bios_parser_helper_dce110.o
-+endif
-+
-+AMD_DAL_FILES += $(AMDDALPATH)/dc/bios/dce110/command_table_helper_dce110.o
-+endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/dal/dc/bios/bios_parser.c
-new file mode 100644
-index 0000000..7a2b247
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/bios_parser.c
-@@ -0,0 +1,4758 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "atom.h"
-+
-+#include "include/adapter_service_interface.h"
-+#include "include/grph_object_ctrl_defs.h"
-+#include "include/bios_parser_interface.h"
-+#include "include/i2caux_interface.h"
-+#include "include/logger_interface.h"
-+
-+#include "command_table.h"
-+#if defined(CONFIG_DRM_AMD_DAL_VBIOS_PRESENT)
-+#include "bios_parser_helper.h"
-+#endif
-+#include "command_table_helper.h"
-+#include "bios_parser.h"
-+
-+#define THREE_PERCENT_OF_10000 300
-+
-+#define LAST_RECORD_TYPE 0xff
-+
-+/* GUID to validate external display connection info table (aka OPM module) */
-+static const uint8_t ext_display_connection_guid[NUMBER_OF_UCHAR_FOR_GUID] = {
-+ 0x91, 0x6E, 0x57, 0x09,
-+ 0x3F, 0x6D, 0xD2, 0x11,
-+ 0x39, 0x8E, 0x00, 0xA0,
-+ 0xC9, 0x69, 0x72, 0x3B};
-+
-+#define GET_IMAGE(type, offset) ((type *) get_image(bp, offset, sizeof(type)))
-+#define DATA_TABLES(table) (bp->master_data_tbl->ListOfDataTables.table)
-+
-+static uint8_t *get_image(struct bios_parser *bp, uint32_t offset,
-+ uint32_t size);
-+static uint32_t get_record_size(uint8_t *record);
-+static uint32_t get_edid_size(const ATOM_FAKE_EDID_PATCH_RECORD *edid);
-+static enum object_type object_type_from_bios_object_id(
-+ uint32_t bios_object_id);
-+static struct graphics_object_id object_id_from_bios_object_id(
-+ uint32_t bios_object_id);
-+static enum object_enum_id enum_id_from_bios_object_id(uint32_t bios_object_id);
-+static enum encoder_id encoder_id_from_bios_object_id(uint32_t bios_object_id);
-+static enum connector_id connector_id_from_bios_object_id(
-+ uint32_t bios_object_id);
-+static uint32_t id_from_bios_object_id(enum object_type type,
-+ uint32_t bios_object_id);
-+static uint32_t gpu_id_from_bios_object_id(uint32_t bios_object_id);
-+static enum generic_id generic_id_from_bios_object_id(uint32_t bios_object_id);
-+static void get_atom_data_table_revision(
-+ ATOM_COMMON_TABLE_HEADER *atom_data_tbl,
-+ struct atom_data_revision *tbl_revision);
-+static uint32_t get_dst_number_from_object(struct bios_parser *bp,
-+ ATOM_OBJECT *object);
-+static uint32_t get_src_obj_list(struct bios_parser *bp, ATOM_OBJECT *object,
-+ uint16_t **id_list);
-+static uint32_t get_dest_obj_list(struct bios_parser *bp,
-+ ATOM_OBJECT *object, uint16_t **id_list);
-+static ATOM_OBJECT *get_bios_object(struct bios_parser *bp,
-+ struct graphics_object_id id);
-+static enum bp_result get_gpio_i2c_info(struct bios_parser *bp,
-+ ATOM_I2C_RECORD *record,
-+ struct graphics_object_i2c_info *info);
-+static ATOM_HPD_INT_RECORD *get_hpd_record(struct bios_parser *bp,
-+ ATOM_OBJECT *object);
-+static struct device_id device_type_from_device_id(uint16_t device_id);
-+static uint32_t signal_to_ss_id(enum as_signal_type signal);
-+static uint32_t get_support_mask_for_device_id(struct device_id device_id);
-+static ATOM_ENCODER_CAP_RECORD *get_encoder_cap_record(
-+ struct bios_parser *bp,
-+ ATOM_OBJECT *object);
-+static void process_ext_display_connection_info(struct bios_parser *bp);
-+
-+#define BIOS_IMAGE_SIZE_OFFSET 2
-+#define BIOS_IMAGE_SIZE_UNIT 512
-+
-+static bool bios_parser_construct(
-+ struct bios_parser *bp,
-+ struct bp_init_data *init,
-+ struct adapter_service *as)
-+{
-+ uint16_t *rom_header_offset = NULL;
-+ ATOM_ROM_HEADER *rom_header = NULL;
-+ ATOM_OBJECT_HEADER *object_info_tbl;
-+ enum dce_version dce_version;
-+
-+ if (!as)
-+ return false;
-+
-+ if (!init)
-+ return false;
-+
-+ if (!init->bios)
-+ return false;
-+
-+ dce_version = dal_adapter_service_get_dce_version(as);
-+ bp->ctx = init->ctx;
-+ bp->as = as;
-+ bp->bios = init->bios;
-+ bp->bios_size = bp->bios[BIOS_IMAGE_SIZE_OFFSET] * BIOS_IMAGE_SIZE_UNIT;
-+ bp->bios_local_image = NULL;
-+ bp->lcd_scale = LCD_SCALE_UNKNOWN;
-+
-+ rom_header_offset =
-+ GET_IMAGE(uint16_t, OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER);
-+
-+ if (!rom_header_offset)
-+ return false;
-+
-+ rom_header = GET_IMAGE(ATOM_ROM_HEADER, *rom_header_offset);
-+
-+ if (!rom_header)
-+ return false;
-+
-+ bp->master_data_tbl =
-+ GET_IMAGE(ATOM_MASTER_DATA_TABLE,
-+ rom_header->usMasterDataTableOffset);
-+
-+ if (!bp->master_data_tbl)
-+ return false;
-+
-+ bp->object_info_tbl_offset = DATA_TABLES(Object_Header);
-+
-+ if (!bp->object_info_tbl_offset)
-+ return false;
-+
-+ object_info_tbl =
-+ GET_IMAGE(ATOM_OBJECT_HEADER, bp->object_info_tbl_offset);
-+
-+ if (!object_info_tbl)
-+ return false;
-+
-+ get_atom_data_table_revision(&object_info_tbl->sHeader,
-+ &bp->object_info_tbl.revision);
-+
-+ if (bp->object_info_tbl.revision.major == 1
-+ && bp->object_info_tbl.revision.minor >= 3) {
-+ ATOM_OBJECT_HEADER_V3 *tbl_v3;
-+
-+ tbl_v3 = GET_IMAGE(ATOM_OBJECT_HEADER_V3,
-+ bp->object_info_tbl_offset);
-+ if (!tbl_v3)
-+ return false;
-+
-+ bp->object_info_tbl.v1_3 = tbl_v3;
-+ } else if (bp->object_info_tbl.revision.major == 1
-+ && bp->object_info_tbl.revision.minor >= 1)
-+ bp->object_info_tbl.v1_1 = object_info_tbl;
-+ else
-+ return false;
-+
-+#if defined(CONFIG_DRM_AMD_DAL_VBIOS_PRESENT)
-+ bp->vbios_helper_data.active = 0;
-+ bp->vbios_helper_data.requested = 0;
-+ dal_bios_parser_init_bios_helper(bp, dce_version);
-+#endif
-+ dal_bios_parser_init_cmd_tbl(bp);
-+ dal_bios_parser_init_cmd_tbl_helper(&bp->cmd_helper, dce_version);
-+
-+ return true;
-+}
-+
-+struct bios_parser *dal_bios_parser_create(
-+ struct bp_init_data *init, struct adapter_service *as)
-+{
-+ struct bios_parser *bp = NULL;
-+
-+ bp = dc_service_alloc(init->ctx, sizeof(struct bios_parser));
-+ if (!bp)
-+ return NULL;
-+
-+ if (bios_parser_construct(bp, init, as))
-+ return bp;
-+
-+ dc_service_free(init->ctx, bp);
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+}
-+
-+static void destruct(struct bios_parser *bp)
-+{
-+ if (bp->bios_local_image)
-+ dc_service_free(bp->ctx, bp->bios_local_image);
-+}
-+
-+void dal_bios_parser_destroy(struct bios_parser **bp)
-+{
-+ if (!bp || !*bp) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ destruct(*bp);
-+
-+ dc_service_free((*bp)->ctx, *bp);
-+ *bp = NULL;
-+}
-+
-+void dal_bios_parser_power_down(struct bios_parser *bp)
-+{
-+#if defined(CONFIG_DRM_AMD_DAL_VBIOS_PRESENT)
-+ dal_bios_parser_set_scratch_lcd_scale(bp, bp->lcd_scale);
-+#endif
-+}
-+
-+void dal_bios_parser_power_up(struct bios_parser *bp)
-+{
-+#if defined(CONFIG_DRM_AMD_DAL_VBIOS_PRESENT)
-+ if (bp->lcd_scale == LCD_SCALE_UNKNOWN)
-+ bp->lcd_scale = dal_bios_parser_get_scratch_lcd_scale(bp);
-+#endif
-+}
-+
-+static uint8_t get_number_of_objects(struct bios_parser *bp, uint32_t offset)
-+{
-+ ATOM_OBJECT_TABLE *table;
-+
-+ uint32_t object_table_offset = bp->object_info_tbl_offset + offset;
-+
-+ table = GET_IMAGE(ATOM_OBJECT_TABLE, object_table_offset);
-+
-+ if (!table)
-+ return 0;
-+ else
-+ return table->ucNumberOfObjects;
-+}
-+
-+uint8_t dal_bios_parser_get_encoders_number(struct bios_parser *bp)
-+{
-+ return get_number_of_objects(bp,
-+ le16_to_cpu(bp->object_info_tbl.v1_1->usEncoderObjectTableOffset));
-+}
-+
-+uint8_t dal_bios_parser_get_connectors_number(struct bios_parser *bp)
-+{
-+ return get_number_of_objects(bp,
-+ le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset));
-+}
-+
-+uint32_t dal_bios_parser_get_oem_ddc_lines_number(struct bios_parser *bp)
-+{
-+ uint32_t number = 0;
-+
-+ if (DATA_TABLES(OemInfo) != 0) {
-+ ATOM_OEM_INFO *info;
-+
-+ info = GET_IMAGE(ATOM_OEM_INFO,
-+ DATA_TABLES(OemInfo));
-+
-+ if (le16_to_cpu(info->sHeader.usStructureSize)
-+ > sizeof(ATOM_COMMON_TABLE_HEADER)) {
-+
-+ number = (le16_to_cpu(info->sHeader.usStructureSize)
-+ - sizeof(ATOM_COMMON_TABLE_HEADER))
-+ / sizeof(ATOM_I2C_ID_CONFIG_ACCESS);
-+
-+ }
-+ }
-+
-+ return number;
-+}
-+
-+struct graphics_object_id dal_bios_parser_get_encoder_id(struct bios_parser *bp,
-+ uint32_t i)
-+{
-+ struct graphics_object_id object_id = dal_graphics_object_id_init(
-+ 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);
-+
-+ uint32_t encoder_table_offset = bp->object_info_tbl_offset
-+ + le16_to_cpu(bp->object_info_tbl.v1_1->usEncoderObjectTableOffset);
-+
-+ ATOM_OBJECT_TABLE *tbl =
-+ GET_IMAGE(ATOM_OBJECT_TABLE, encoder_table_offset);
-+
-+ if (tbl && tbl->ucNumberOfObjects > i) {
-+ const uint16_t id = le16_to_cpu(tbl->asObjects[i].usObjectID);
-+
-+ object_id = object_id_from_bios_object_id(id);
-+ }
-+
-+ return object_id;
-+}
-+
-+struct graphics_object_id dal_bios_parser_get_connector_id(
-+ struct bios_parser *bp,
-+ uint8_t i)
-+{
-+ struct graphics_object_id object_id = dal_graphics_object_id_init(
-+ 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN);
-+
-+ uint32_t connector_table_offset = bp->object_info_tbl_offset
-+ + le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset);
-+
-+ ATOM_OBJECT_TABLE *tbl =
-+ GET_IMAGE(ATOM_OBJECT_TABLE, connector_table_offset);
-+
-+ if (tbl && tbl->ucNumberOfObjects > i) {
-+ const uint16_t id = le16_to_cpu(tbl->asObjects[i].usObjectID);
-+
-+ object_id = object_id_from_bios_object_id(id);
-+ }
-+
-+ return object_id;
-+}
-+
-+uint32_t dal_bios_parser_get_src_number(struct bios_parser *bp,
-+ struct graphics_object_id id)
-+{
-+ uint32_t offset;
-+ uint8_t *number;
-+ ATOM_OBJECT *object;
-+
-+ object = get_bios_object(bp, id);
-+
-+ if (!object) {
-+ BREAK_TO_DEBUGGER(); /* Invalid object id */
-+ return 0;
-+ }
-+
-+ offset = le16_to_cpu(object->usSrcDstTableOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ number = GET_IMAGE(uint8_t, offset);
-+ if (!number)
-+ return 0;
-+
-+ return *number;
-+}
-+
-+uint32_t dal_bios_parser_get_dst_number(struct bios_parser *bp,
-+ struct graphics_object_id id)
-+{
-+ ATOM_OBJECT *object = get_bios_object(bp, id);
-+
-+ return get_dst_number_from_object(bp, object);
-+}
-+
-+enum bp_result dal_bios_parser_get_src_obj(struct bios_parser *bp,
-+ struct graphics_object_id object_id, uint32_t index,
-+ struct graphics_object_id *src_object_id)
-+{
-+ uint32_t number;
-+ uint16_t *id;
-+ ATOM_OBJECT *object;
-+
-+ if (!src_object_id)
-+ return BP_RESULT_BADINPUT;
-+
-+ object = get_bios_object(bp, object_id);
-+
-+ if (!object) {
-+ BREAK_TO_DEBUGGER(); /* Invalid object id */
-+ return BP_RESULT_BADINPUT;
-+ }
-+
-+ number = get_src_obj_list(bp, object, &id);
-+
-+ if (number <= index)
-+ return BP_RESULT_BADINPUT;
-+
-+ *src_object_id = object_id_from_bios_object_id(id[index]);
-+
-+ return BP_RESULT_OK;
-+}
-+
-+enum bp_result dal_bios_parser_get_dst_obj(struct bios_parser *bp,
-+ struct graphics_object_id object_id, uint32_t index,
-+ struct graphics_object_id *dest_object_id)
-+{
-+ uint32_t number;
-+ uint16_t *id;
-+ ATOM_OBJECT *object;
-+
-+ if (!dest_object_id)
-+ return BP_RESULT_BADINPUT;
-+
-+ object = get_bios_object(bp, object_id);
-+
-+ number = get_dest_obj_list(bp, object, &id);
-+
-+ if (number <= index)
-+ return BP_RESULT_BADINPUT;
-+
-+ *dest_object_id = object_id_from_bios_object_id(id[index]);
-+
-+ return BP_RESULT_OK;
-+}
-+
-+enum bp_result dal_bios_parser_get_oem_ddc_info(struct bios_parser *bp,
-+ uint32_t index,
-+ struct graphics_object_i2c_info *info)
-+{
-+
-+ if (!info)
-+ return BP_RESULT_BADINPUT;
-+
-+ if (DATA_TABLES(OemInfo) != 0) {
-+ ATOM_OEM_INFO *tbl;
-+
-+ tbl = GET_IMAGE(ATOM_OEM_INFO, DATA_TABLES(OemInfo));
-+
-+ if (le16_to_cpu(tbl->sHeader.usStructureSize)
-+ > sizeof(ATOM_COMMON_TABLE_HEADER)) {
-+ ATOM_I2C_RECORD record;
-+ ATOM_I2C_ID_CONFIG_ACCESS *config;
-+
-+ dc_service_memset(&record, 0, sizeof(record));
-+
-+ config = &tbl->sucI2cId + index - 1;
-+
-+ record.sucI2cId.bfHW_Capable =
-+ config->sbfAccess.bfHW_Capable;
-+ record.sucI2cId.bfI2C_LineMux =
-+ config->sbfAccess.bfI2C_LineMux;
-+ record.sucI2cId.bfHW_EngineID =
-+ config->sbfAccess.bfHW_EngineID;
-+
-+ return get_gpio_i2c_info(bp, &record, info);
-+ }
-+ }
-+
-+ return BP_RESULT_NORECORD;
-+}
-+
-+enum bp_result dal_bios_parser_get_i2c_info(struct bios_parser *bp,
-+ struct graphics_object_id id,
-+ struct graphics_object_i2c_info *info)
-+{
-+ uint32_t offset;
-+ ATOM_OBJECT *object;
-+ ATOM_COMMON_RECORD_HEADER *header;
-+ ATOM_I2C_RECORD *record;
-+
-+ if (!info)
-+ return BP_RESULT_BADINPUT;
-+
-+ object = get_bios_object(bp, id);
-+
-+ if (!object)
-+ return BP_RESULT_BADINPUT;
-+
-+ offset = le16_to_cpu(object->usRecordOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ for (;;) {
-+ header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
-+
-+ if (!header)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ if (LAST_RECORD_TYPE == header->ucRecordType ||
-+ !header->ucRecordSize)
-+ break;
-+
-+ if (ATOM_I2C_RECORD_TYPE == header->ucRecordType
-+ && sizeof(ATOM_I2C_RECORD) <= header->ucRecordSize) {
-+ /* get the I2C info */
-+ record = (ATOM_I2C_RECORD *) header;
-+
-+ if (get_gpio_i2c_info(bp, record, info) == BP_RESULT_OK)
-+ return BP_RESULT_OK;
-+ }
-+
-+ offset += header->ucRecordSize;
-+ }
-+
-+ return BP_RESULT_NORECORD;
-+}
-+
-+static enum bp_result get_voltage_ddc_info_v1(uint8_t *i2c_line,
-+ ATOM_COMMON_TABLE_HEADER *header,
-+ uint8_t *address)
-+{
-+ enum bp_result result = BP_RESULT_NORECORD;
-+ ATOM_VOLTAGE_OBJECT_INFO *info =
-+ (ATOM_VOLTAGE_OBJECT_INFO *) address;
-+
-+ uint8_t *voltage_current_object = (uint8_t *) &info->asVoltageObj[0];
-+
-+ while ((address + le16_to_cpu(header->usStructureSize)) > voltage_current_object) {
-+ ATOM_VOLTAGE_OBJECT *object =
-+ (ATOM_VOLTAGE_OBJECT *) voltage_current_object;
-+
-+ if ((object->ucVoltageType == SET_VOLTAGE_INIT_MODE) &&
-+ (object->ucVoltageType &
-+ VOLTAGE_CONTROLLED_BY_I2C_MASK)) {
-+
-+ *i2c_line = object->asControl.ucVoltageControlI2cLine
-+ ^ 0x90;
-+ result = BP_RESULT_OK;
-+ break;
-+ }
-+
-+ voltage_current_object += object->ucSize;
-+ }
-+ return result;
-+}
-+
-+static enum bp_result get_voltage_ddc_info_v3(uint8_t *i2c_line,
-+ uint32_t index,
-+ ATOM_COMMON_TABLE_HEADER *header,
-+ uint8_t *address)
-+{
-+ enum bp_result result = BP_RESULT_NORECORD;
-+ ATOM_VOLTAGE_OBJECT_INFO_V3_1 *info =
-+ (ATOM_VOLTAGE_OBJECT_INFO_V3_1 *) address;
-+
-+ uint8_t *voltage_current_object =
-+ (uint8_t *) (&(info->asVoltageObj[0]));
-+
-+ while ((address + le16_to_cpu(header->usStructureSize)) > voltage_current_object) {
-+ ATOM_I2C_VOLTAGE_OBJECT_V3 *object =
-+ (ATOM_I2C_VOLTAGE_OBJECT_V3 *) voltage_current_object;
-+
-+ if (object->sHeader.ucVoltageMode ==
-+ ATOM_INIT_VOLTAGE_REGULATOR) {
-+ if (object->sHeader.ucVoltageType == index) {
-+ *i2c_line = object->ucVoltageControlI2cLine
-+ ^ 0x90;
-+ result = BP_RESULT_OK;
-+ break;
-+ }
-+ }
-+
-+ voltage_current_object += le16_to_cpu(object->sHeader.usSize);
-+ }
-+ return result;
-+}
-+
-+enum bp_result dal_bios_parser_get_voltage_ddc_info(struct bios_parser *bp,
-+ uint32_t index,
-+ struct graphics_object_i2c_info *info)
-+{
-+ uint8_t i2c_line = 0;
-+ enum bp_result result = BP_RESULT_NORECORD;
-+ uint8_t *voltage_info_address;
-+ ATOM_COMMON_TABLE_HEADER *header;
-+ struct atom_data_revision revision = {0};
-+
-+ if (!DATA_TABLES(VoltageObjectInfo))
-+ return result;
-+
-+ voltage_info_address = get_image(bp,
-+ DATA_TABLES(VoltageObjectInfo),
-+ sizeof(ATOM_COMMON_TABLE_HEADER));
-+
-+ header = (ATOM_COMMON_TABLE_HEADER *) voltage_info_address;
-+
-+ get_atom_data_table_revision(header, &revision);
-+
-+ switch (revision.major) {
-+ case 1:
-+ case 2:
-+ result = get_voltage_ddc_info_v1(&i2c_line, header,
-+ voltage_info_address);
-+ break;
-+ case 3:
-+ if (revision.minor != 1)
-+ break;
-+ result = get_voltage_ddc_info_v3(&i2c_line, index, header,
-+ voltage_info_address);
-+ break;
-+ }
-+
-+ if (result == BP_RESULT_OK)
-+ result = dal_bios_parser_get_thermal_ddc_info(bp,
-+ i2c_line, info);
-+
-+
-+ return result;
-+}
-+
-+enum bp_result dal_bios_parser_get_thermal_ddc_info(
-+ struct bios_parser *bp,
-+ uint32_t i2c_channel_id,
-+ struct graphics_object_i2c_info *info)
-+{
-+ ATOM_I2C_ID_CONFIG_ACCESS *config;
-+ ATOM_I2C_RECORD record;
-+
-+ if (!info)
-+ return BP_RESULT_BADINPUT;
-+
-+ config = (ATOM_I2C_ID_CONFIG_ACCESS *) &i2c_channel_id;
-+
-+ record.sucI2cId.bfHW_Capable = config->sbfAccess.bfHW_Capable;
-+ record.sucI2cId.bfI2C_LineMux = config->sbfAccess.bfI2C_LineMux;
-+ record.sucI2cId.bfHW_EngineID = config->sbfAccess.bfHW_EngineID;
-+
-+ return get_gpio_i2c_info(bp, &record, info);
-+}
-+
-+enum bp_result dal_bios_parser_get_ddc_info_for_i2c_line(struct bios_parser *bp,
-+ uint8_t i2c_line, struct graphics_object_i2c_info *info)
-+{
-+ uint32_t offset;
-+ ATOM_OBJECT *object;
-+ ATOM_OBJECT_TABLE *table;
-+ uint32_t i;
-+
-+ if (!info)
-+ return BP_RESULT_BADINPUT;
-+
-+ offset = le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset);
-+
-+ offset += bp->object_info_tbl_offset;
-+
-+ table = GET_IMAGE(ATOM_OBJECT_TABLE, offset);
-+
-+ if (!table)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ for (i = 0; i < table->ucNumberOfObjects; i++) {
-+ object = &table->asObjects[i];
-+
-+ if (!object) {
-+ BREAK_TO_DEBUGGER(); /* Invalid object id */
-+ return BP_RESULT_BADINPUT;
-+ }
-+
-+ offset = le16_to_cpu(object->usRecordOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ for (;;) {
-+ ATOM_COMMON_RECORD_HEADER *header =
-+ GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
-+
-+ if (!header)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ offset += header->ucRecordSize;
-+
-+ if (LAST_RECORD_TYPE == header->ucRecordType ||
-+ !header->ucRecordSize)
-+ break;
-+
-+ if (ATOM_I2C_RECORD_TYPE == header->ucRecordType
-+ && sizeof(ATOM_I2C_RECORD) <=
-+ header->ucRecordSize) {
-+ ATOM_I2C_RECORD *record =
-+ (ATOM_I2C_RECORD *) header;
-+
-+ if (i2c_line != record->sucI2cId.bfI2C_LineMux)
-+ continue;
-+
-+ /* get the I2C info */
-+ if (get_gpio_i2c_info(bp, record, info) ==
-+ BP_RESULT_OK)
-+ return BP_RESULT_OK;
-+ }
-+ }
-+ }
-+
-+ return BP_RESULT_NORECORD;
-+}
-+
-+enum bp_result dal_bios_parser_get_hpd_info(struct bios_parser *bp,
-+ struct graphics_object_id id,
-+ struct graphics_object_hpd_info *info)
-+{
-+ ATOM_OBJECT *object;
-+ ATOM_HPD_INT_RECORD *record = NULL;
-+
-+ if (!info)
-+ return BP_RESULT_BADINPUT;
-+
-+ object = get_bios_object(bp, id);
-+
-+ if (!object)
-+ return BP_RESULT_BADINPUT;
-+
-+ record = get_hpd_record(bp, object);
-+
-+ if (record != NULL) {
-+ info->hpd_int_gpio_uid = record->ucHPDIntGPIOID;
-+ info->hpd_active = record->ucPlugged_PinState;
-+ return BP_RESULT_OK;
-+ }
-+
-+ return BP_RESULT_NORECORD;
-+}
-+
-+uint32_t dal_bios_parser_get_gpio_record(
-+ struct bios_parser *bp,
-+ struct graphics_object_id id,
-+ struct bp_gpio_cntl_info *gpio_record,
-+ uint32_t record_size)
-+{
-+ ATOM_COMMON_RECORD_HEADER *header = NULL;
-+ ATOM_OBJECT_GPIO_CNTL_RECORD *record = NULL;
-+ ATOM_OBJECT *object = get_bios_object(bp, id);
-+ uint32_t offset;
-+ uint32_t pins_number;
-+ uint32_t i;
-+
-+ if (!object)
-+ return 0;
-+
-+ /* Initialise offset */
-+ offset = le16_to_cpu(object->usRecordOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ for (;;) {
-+ /* Get record header */
-+ header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
-+ if (!header || header->ucRecordType == LAST_RECORD_TYPE ||
-+ !header->ucRecordSize)
-+ break;
-+
-+ /* If this is gpio control record - stop. We found the record */
-+ if (header->ucRecordType == ATOM_OBJECT_GPIO_CNTL_RECORD_TYPE
-+ && header->ucRecordSize
-+ >= sizeof(ATOM_OBJECT_GPIO_CNTL_RECORD)) {
-+ record = (ATOM_OBJECT_GPIO_CNTL_RECORD *) header;
-+ break;
-+ }
-+
-+ /* Advance to next record */
-+ offset += header->ucRecordSize;
-+ }
-+
-+ /* If we did not find a record - return */
-+ if (!record)
-+ return 0;
-+
-+ /* Extract gpio IDs from bios record (make sure we do not exceed passed
-+ * array size) */
-+ pins_number = (record->ucNumberOfPins < record_size ?
-+ record->ucNumberOfPins : record_size);
-+ for (i = 0; i < pins_number; i++) {
-+ uint8_t output_state = ((record->asGpio[i].ucGPIO_PinState
-+ & GPIO_PIN_OUTPUT_STATE_MASK)
-+ >> GPIO_PIN_OUTPUT_STATE_SHIFT);
-+ gpio_record[i].id = record->asGpio[i].ucGPIOID;
-+
-+ switch (output_state) {
-+ case GPIO_PIN_STATE_ACTIVE_LOW:
-+ gpio_record[i].state =
-+ GPIO_PIN_OUTPUT_STATE_ACTIVE_LOW;
-+ break;
-+
-+ case GPIO_PIN_STATE_ACTIVE_HIGH:
-+ gpio_record[i].state =
-+ GPIO_PIN_OUTPUT_STATE_ACTIVE_HIGH;
-+ break;
-+
-+ default:
-+ BREAK_TO_DEBUGGER(); /* Invalid Pin Output State */
-+ break;
-+ }
-+ }
-+
-+ return pins_number;
-+}
-+
-+enum bp_result dal_bios_parser_get_device_tag_record(
-+ struct bios_parser *bp,
-+ ATOM_OBJECT *object,
-+ ATOM_CONNECTOR_DEVICE_TAG_RECORD **record)
-+{
-+ ATOM_COMMON_RECORD_HEADER *header;
-+ uint32_t offset;
-+
-+ offset = le16_to_cpu(object->usRecordOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ for (;;) {
-+ header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
-+
-+ if (!header)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ offset += header->ucRecordSize;
-+
-+ if (LAST_RECORD_TYPE == header->ucRecordType ||
-+ !header->ucRecordSize)
-+ break;
-+
-+ if (ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE !=
-+ header->ucRecordType)
-+ continue;
-+
-+ if (sizeof(ATOM_CONNECTOR_DEVICE_TAG) > header->ucRecordSize)
-+ continue;
-+
-+ *record = (ATOM_CONNECTOR_DEVICE_TAG_RECORD *) header;
-+ return BP_RESULT_OK;
-+ }
-+
-+ return BP_RESULT_NORECORD;
-+}
-+
-+enum bp_result dal_bios_parser_get_device_tag(
-+ struct bios_parser *bp,
-+ struct graphics_object_id connector_object_id,
-+ uint32_t device_tag_index,
-+ struct connector_device_tag_info *info)
-+{
-+ ATOM_OBJECT *object;
-+ ATOM_CONNECTOR_DEVICE_TAG_RECORD *record = NULL;
-+ ATOM_CONNECTOR_DEVICE_TAG *device_tag;
-+
-+ if (!info)
-+ return BP_RESULT_BADINPUT;
-+
-+ /* getBiosObject will return MXM object */
-+ object = get_bios_object(bp, connector_object_id);
-+
-+ if (!object) {
-+ BREAK_TO_DEBUGGER(); /* Invalid object id */
-+ return BP_RESULT_BADINPUT;
-+ }
-+
-+ if (dal_bios_parser_get_device_tag_record(bp, object, &record)
-+ != BP_RESULT_OK)
-+ return BP_RESULT_NORECORD;
-+
-+ if (device_tag_index >= record->ucNumberOfDevice)
-+ return BP_RESULT_NORECORD;
-+
-+ device_tag = &record->asDeviceTag[device_tag_index];
-+
-+ info->acpi_device = le32_to_cpu(device_tag->ulACPIDeviceEnum);
-+ info->dev_id =
-+ device_type_from_device_id(le16_to_cpu(device_tag->usDeviceID));
-+
-+ return BP_RESULT_OK;
-+}
-+
-+static enum bp_result get_firmware_info_v1_4(
-+ struct bios_parser *bp,
-+ struct firmware_info *info);
-+static enum bp_result get_firmware_info_v2_1(
-+ struct bios_parser *bp,
-+ struct firmware_info *info);
-+static enum bp_result get_firmware_info_v2_2(
-+ struct bios_parser *bp,
-+ struct firmware_info *info);
-+
-+enum bp_result dal_bios_parser_get_firmware_info(
-+ struct bios_parser *bp,
-+ struct firmware_info *info)
-+{
-+ enum bp_result result = BP_RESULT_BADBIOSTABLE;
-+ ATOM_COMMON_TABLE_HEADER *header;
-+ struct atom_data_revision revision;
-+
-+ if (info && DATA_TABLES(FirmwareInfo)) {
-+ header = GET_IMAGE(ATOM_COMMON_TABLE_HEADER,
-+ DATA_TABLES(FirmwareInfo));
-+ get_atom_data_table_revision(header, &revision);
-+ switch (revision.major) {
-+ case 1:
-+ switch (revision.minor) {
-+ case 4:
-+ result = get_firmware_info_v1_4(bp, info);
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+
-+ case 2:
-+ switch (revision.minor) {
-+ case 1:
-+ result = get_firmware_info_v2_1(bp, info);
-+ break;
-+ case 2:
-+ result = get_firmware_info_v2_2(bp, info);
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ return result;
-+}
-+
-+static enum bp_result get_firmware_info_v1_4(
-+ struct bios_parser *bp,
-+ struct firmware_info *info)
-+{
-+ ATOM_FIRMWARE_INFO_V1_4 *firmware_info =
-+ GET_IMAGE(ATOM_FIRMWARE_INFO_V1_4,
-+ DATA_TABLES(FirmwareInfo));
-+
-+ if (!info)
-+ return BP_RESULT_BADINPUT;
-+
-+ if (!firmware_info)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ dc_service_memset(info, 0, sizeof(*info));
-+
-+ /* Pixel clock pll information. We need to convert from 10KHz units into
-+ * KHz units */
-+ info->pll_info.crystal_frequency =
-+ le16_to_cpu(firmware_info->usReferenceClock) * 10;
-+ info->pll_info.min_input_pxl_clk_pll_frequency =
-+ le16_to_cpu(firmware_info->usMinPixelClockPLL_Input) * 10;
-+ info->pll_info.max_input_pxl_clk_pll_frequency =
-+ le16_to_cpu(firmware_info->usMaxPixelClockPLL_Input) * 10;
-+ info->pll_info.min_output_pxl_clk_pll_frequency =
-+ le32_to_cpu(firmware_info->ulMinPixelClockPLL_Output) * 10;
-+ info->pll_info.max_output_pxl_clk_pll_frequency =
-+ le32_to_cpu(firmware_info->ulMaxPixelClockPLL_Output) * 10;
-+
-+ if (firmware_info->usFirmwareCapability.sbfAccess.MemoryClockSS_Support)
-+ /* Since there is no information on the SS, report conservative
-+ * value 3% for bandwidth calculation */
-+ /* unit of 0.01% */
-+ info->feature.memory_clk_ss_percentage = THREE_PERCENT_OF_10000;
-+
-+ if (firmware_info->usFirmwareCapability.sbfAccess.EngineClockSS_Support)
-+ /* Since there is no information on the SS,report conservative
-+ * value 3% for bandwidth calculation */
-+ /* unit of 0.01% */
-+ info->feature.engine_clk_ss_percentage = THREE_PERCENT_OF_10000;
-+
-+ return BP_RESULT_OK;
-+}
-+
-+static enum bp_result get_ss_info_v3_1(
-+ struct bios_parser *bp,
-+ uint32_t id,
-+ uint32_t index,
-+ struct spread_spectrum_info *ss_info);
-+
-+static enum bp_result get_firmware_info_v2_1(
-+ struct bios_parser *bp,
-+ struct firmware_info *info)
-+{
-+ ATOM_FIRMWARE_INFO_V2_1 *firmwareInfo =
-+ GET_IMAGE(ATOM_FIRMWARE_INFO_V2_1, DATA_TABLES(FirmwareInfo));
-+ struct spread_spectrum_info internalSS;
-+ uint32_t index;
-+
-+ if (!info)
-+ return BP_RESULT_BADINPUT;
-+
-+ if (!firmwareInfo)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ dc_service_memset(info, 0, sizeof(*info));
-+
-+ /* Pixel clock pll information. We need to convert from 10KHz units into
-+ * KHz units */
-+ info->pll_info.crystal_frequency =
-+ le16_to_cpu(firmwareInfo->usCoreReferenceClock) * 10;
-+ info->pll_info.min_input_pxl_clk_pll_frequency =
-+ le16_to_cpu(firmwareInfo->usMinPixelClockPLL_Input) * 10;
-+ info->pll_info.max_input_pxl_clk_pll_frequency =
-+ le16_to_cpu(firmwareInfo->usMaxPixelClockPLL_Input) * 10;
-+ info->pll_info.min_output_pxl_clk_pll_frequency =
-+ le32_to_cpu(firmwareInfo->ulMinPixelClockPLL_Output) * 10;
-+ info->pll_info.max_output_pxl_clk_pll_frequency =
-+ le32_to_cpu(firmwareInfo->ulMaxPixelClockPLL_Output) * 10;
-+ info->default_display_engine_pll_frequency =
-+ le32_to_cpu(firmwareInfo->ulDefaultDispEngineClkFreq) * 10;
-+ info->external_clock_source_frequency_for_dp =
-+ le16_to_cpu(firmwareInfo->usUniphyDPModeExtClkFreq) * 10;
-+ info->min_allowed_bl_level = firmwareInfo->ucMinAllowedBL_Level;
-+
-+ /* There should be only one entry in the SS info table for Memory Clock
-+ */
-+ index = 0;
-+ if (firmwareInfo->usFirmwareCapability.sbfAccess.MemoryClockSS_Support)
-+ /* Since there is no information for external SS, report
-+ * conservative value 3% for bandwidth calculation */
-+ /* unit of 0.01% */
-+ info->feature.memory_clk_ss_percentage = THREE_PERCENT_OF_10000;
-+ else if (get_ss_info_v3_1(bp,
-+ ASIC_INTERNAL_MEMORY_SS, index, &internalSS) == BP_RESULT_OK) {
-+ if (internalSS.spread_spectrum_percentage) {
-+ info->feature.memory_clk_ss_percentage =
-+ internalSS.spread_spectrum_percentage;
-+ if (internalSS.type.CENTER_MODE) {
-+ /* if it is centermode, the exact SS Percentage
-+ * will be round up of half of the percentage
-+ * reported in the SS table */
-+ ++info->feature.memory_clk_ss_percentage;
-+ info->feature.memory_clk_ss_percentage /= 2;
-+ }
-+ }
-+ }
-+
-+ /* There should be only one entry in the SS info table for Engine Clock
-+ */
-+ index = 1;
-+ if (firmwareInfo->usFirmwareCapability.sbfAccess.EngineClockSS_Support)
-+ /* Since there is no information for external SS, report
-+ * conservative value 3% for bandwidth calculation */
-+ /* unit of 0.01% */
-+ info->feature.engine_clk_ss_percentage = THREE_PERCENT_OF_10000;
-+ else if (get_ss_info_v3_1(bp,
-+ ASIC_INTERNAL_ENGINE_SS, index, &internalSS) == BP_RESULT_OK) {
-+ if (internalSS.spread_spectrum_percentage) {
-+ info->feature.engine_clk_ss_percentage =
-+ internalSS.spread_spectrum_percentage;
-+ if (internalSS.type.CENTER_MODE) {
-+ /* if it is centermode, the exact SS Percentage
-+ * will be round up of half of the percentage
-+ * reported in the SS table */
-+ ++info->feature.engine_clk_ss_percentage;
-+ info->feature.engine_clk_ss_percentage /= 2;
-+ }
-+ }
-+ }
-+
-+ return BP_RESULT_OK;
-+}
-+
-+static enum bp_result get_firmware_info_v2_2(
-+ struct bios_parser *bp,
-+ struct firmware_info *info)
-+{
-+ ATOM_FIRMWARE_INFO_V2_2 *firmware_info;
-+ struct spread_spectrum_info internal_ss;
-+ uint32_t index;
-+
-+ if (!info)
-+ return BP_RESULT_BADINPUT;
-+
-+ firmware_info = GET_IMAGE(ATOM_FIRMWARE_INFO_V2_2,
-+ DATA_TABLES(FirmwareInfo));
-+
-+ if (!firmware_info)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ dc_service_memset(info, 0, sizeof(*info));
-+
-+ /* Pixel clock pll information. We need to convert from 10KHz units into
-+ * KHz units */
-+ info->pll_info.crystal_frequency =
-+ le16_to_cpu(firmware_info->usCoreReferenceClock) * 10;
-+ info->pll_info.min_input_pxl_clk_pll_frequency =
-+ le16_to_cpu(firmware_info->usMinPixelClockPLL_Input) * 10;
-+ info->pll_info.max_input_pxl_clk_pll_frequency =
-+ le16_to_cpu(firmware_info->usMaxPixelClockPLL_Input) * 10;
-+ info->pll_info.min_output_pxl_clk_pll_frequency =
-+ le32_to_cpu(firmware_info->ulMinPixelClockPLL_Output) * 10;
-+ info->pll_info.max_output_pxl_clk_pll_frequency =
-+ le32_to_cpu(firmware_info->ulMaxPixelClockPLL_Output) * 10;
-+ info->default_display_engine_pll_frequency =
-+ le32_to_cpu(firmware_info->ulDefaultDispEngineClkFreq) * 10;
-+ info->external_clock_source_frequency_for_dp =
-+ le16_to_cpu(firmware_info->usUniphyDPModeExtClkFreq) * 10;
-+
-+ /* There should be only one entry in the SS info table for Memory Clock
-+ */
-+ index = 0;
-+ if (firmware_info->usFirmwareCapability.sbfAccess.MemoryClockSS_Support)
-+ /* Since there is no information for external SS, report
-+ * conservative value 3% for bandwidth calculation */
-+ /* unit of 0.01% */
-+ info->feature.memory_clk_ss_percentage = THREE_PERCENT_OF_10000;
-+ else if (get_ss_info_v3_1(bp,
-+ ASIC_INTERNAL_MEMORY_SS, index, &internal_ss) == BP_RESULT_OK) {
-+ if (internal_ss.spread_spectrum_percentage) {
-+ info->feature.memory_clk_ss_percentage =
-+ internal_ss.spread_spectrum_percentage;
-+ if (internal_ss.type.CENTER_MODE) {
-+ /* if it is centermode, the exact SS Percentage
-+ * will be round up of half of the percentage
-+ * reported in the SS table */
-+ ++info->feature.memory_clk_ss_percentage;
-+ info->feature.memory_clk_ss_percentage /= 2;
-+ }
-+ }
-+ }
-+
-+ /* There should be only one entry in the SS info table for Engine Clock
-+ */
-+ index = 1;
-+ if (firmware_info->usFirmwareCapability.sbfAccess.EngineClockSS_Support)
-+ /* Since there is no information for external SS, report
-+ * conservative value 3% for bandwidth calculation */
-+ /* unit of 0.01% */
-+ info->feature.engine_clk_ss_percentage = THREE_PERCENT_OF_10000;
-+ else if (get_ss_info_v3_1(bp,
-+ ASIC_INTERNAL_ENGINE_SS, index, &internal_ss) == BP_RESULT_OK) {
-+ if (internal_ss.spread_spectrum_percentage) {
-+ info->feature.engine_clk_ss_percentage =
-+ internal_ss.spread_spectrum_percentage;
-+ if (internal_ss.type.CENTER_MODE) {
-+ /* if it is centermode, the exact SS Percentage
-+ * will be round up of half of the percentage
-+ * reported in the SS table */
-+ ++info->feature.engine_clk_ss_percentage;
-+ info->feature.engine_clk_ss_percentage /= 2;
-+ }
-+ }
-+ }
-+
-+ /* Remote Display */
-+ info->remote_display_config = firmware_info->ucRemoteDisplayConfig;
-+
-+ /* Is allowed minimum BL level */
-+ info->min_allowed_bl_level = firmware_info->ucMinAllowedBL_Level;
-+ /* Used starting from CI */
-+ info->smu_gpu_pll_output_freq =
-+ (uint32_t) (le32_to_cpu(firmware_info->ulGPUPLL_OutputFreq) * 10);
-+
-+ return BP_RESULT_OK;
-+}
-+
-+static enum bp_result get_ss_info_v3_1(
-+ struct bios_parser *bp,
-+ uint32_t id,
-+ uint32_t index,
-+ struct spread_spectrum_info *ss_info)
-+{
-+ ATOM_ASIC_INTERNAL_SS_INFO_V3 *ss_table_header_include;
-+ ATOM_ASIC_SS_ASSIGNMENT_V3 *tbl;
-+ uint32_t table_size;
-+ uint32_t i;
-+ uint32_t table_index = 0;
-+
-+ if (!ss_info)
-+ return BP_RESULT_BADINPUT;
-+
-+ if (!DATA_TABLES(ASIC_InternalSS_Info))
-+ return BP_RESULT_UNSUPPORTED;
-+
-+ ss_table_header_include = GET_IMAGE(ATOM_ASIC_INTERNAL_SS_INFO_V3,
-+ DATA_TABLES(ASIC_InternalSS_Info));
-+ table_size =
-+ (le16_to_cpu(ss_table_header_include->sHeader.usStructureSize)
-+ - sizeof(ATOM_COMMON_TABLE_HEADER))
-+ / sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3);
-+
-+ tbl = (ATOM_ASIC_SS_ASSIGNMENT_V3 *)
-+ &ss_table_header_include->asSpreadSpectrum[0];
-+
-+ dc_service_memset(ss_info, 0, sizeof(struct spread_spectrum_info));
-+
-+ for (i = 0; i < table_size; i++) {
-+ if (tbl[i].ucClockIndication != (uint8_t) id)
-+ continue;
-+
-+ if (table_index != index) {
-+ table_index++;
-+ continue;
-+ }
-+ /* VBIOS introduced new defines for Version 3, same values as
-+ * before, so now use these new ones for Version 3.
-+ * Shouldn't affect field VBIOS's V3 as define values are still
-+ * same.
-+ * #define SS_MODE_V3_CENTRE_SPREAD_MASK 0x01
-+ * #define SS_MODE_V3_EXTERNAL_SS_MASK 0x02
-+
-+ * Old VBIOS defines:
-+ * #define ATOM_SS_CENTRE_SPREAD_MODE_MASK 0x00000001
-+ * #define ATOM_EXTERNAL_SS_MASK 0x00000002
-+ */
-+
-+ if (SS_MODE_V3_EXTERNAL_SS_MASK & tbl[i].ucSpreadSpectrumMode)
-+ ss_info->type.EXTERNAL = true;
-+
-+ if (SS_MODE_V3_CENTRE_SPREAD_MASK & tbl[i].ucSpreadSpectrumMode)
-+ ss_info->type.CENTER_MODE = true;
-+
-+ /* Older VBIOS (in field) always provides SS percentage in 0.01%
-+ * units set Divider to 100 */
-+ ss_info->spread_percentage_divider = 100;
-+
-+ /* #define SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK 0x10 */
-+ if (SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK
-+ & tbl[i].ucSpreadSpectrumMode)
-+ ss_info->spread_percentage_divider = 1000;
-+
-+ ss_info->type.STEP_AND_DELAY_INFO = false;
-+ /* convert [10KHz] into [KHz] */
-+ ss_info->target_clock_range =
-+ le32_to_cpu(tbl[i].ulTargetClockRange) * 10;
-+ ss_info->spread_spectrum_percentage =
-+ (uint32_t)le16_to_cpu(tbl[i].usSpreadSpectrumPercentage);
-+ ss_info->spread_spectrum_range =
-+ (uint32_t)(le16_to_cpu(tbl[i].usSpreadRateIn10Hz) * 10);
-+
-+ return BP_RESULT_OK;
-+ }
-+ return BP_RESULT_NORECORD;
-+}
-+
-+enum bp_result dal_bios_parser_transmitter_control(
-+ struct bios_parser *bp,
-+ struct bp_transmitter_control *cntl)
-+{
-+ if (!bp->cmd_tbl.transmitter_control)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.transmitter_control(bp, cntl);
-+}
-+
-+enum bp_result dal_bios_parser_encoder_control(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl)
-+{
-+ if (!bp->cmd_tbl.dig_encoder_control)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.dig_encoder_control(bp, cntl);
-+}
-+
-+enum bp_result dal_bios_parser_adjust_pixel_clock(
-+ struct bios_parser *bp,
-+ struct bp_adjust_pixel_clock_parameters *bp_params)
-+{
-+ if (!bp->cmd_tbl.adjust_display_pll)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.adjust_display_pll(bp, bp_params);
-+}
-+
-+enum bp_result dal_bios_parser_set_pixel_clock(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params)
-+{
-+ if (!bp->cmd_tbl.set_pixel_clock)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.set_pixel_clock(bp, bp_params);
-+}
-+
-+enum bp_result dal_bios_parser_enable_spread_spectrum_on_ppll(
-+ struct bios_parser *bp,
-+ struct bp_spread_spectrum_parameters *bp_params,
-+ bool enable)
-+{
-+ if (!bp->cmd_tbl.enable_spread_spectrum_on_ppll)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.enable_spread_spectrum_on_ppll(
-+ bp, bp_params, enable);
-+
-+}
-+
-+enum bp_result dal_bios_parser_program_crtc_timing(
-+ struct bios_parser *bp,
-+ struct bp_hw_crtc_timing_parameters *bp_params)
-+{
-+ if (!bp->cmd_tbl.set_crtc_timing)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.set_crtc_timing(bp, bp_params);
-+}
-+
-+enum bp_result dal_bios_parser_program_display_engine_pll(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params)
-+{
-+
-+ if (!bp->cmd_tbl.program_clock)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.program_clock(bp, bp_params);
-+
-+}
-+
-+enum signal_type dal_bios_parser_dac_load_detect(
-+ struct bios_parser *bp,
-+ struct graphics_object_id encoder,
-+ struct graphics_object_id connector,
-+ enum signal_type display_signal)
-+{
-+ if (!bp->cmd_tbl.dac_load_detection)
-+ return SIGNAL_TYPE_NONE;
-+
-+ return bp->cmd_tbl.dac_load_detection(bp, encoder, connector,
-+ display_signal);
-+}
-+
-+enum bp_result dal_bios_parser_get_divider_for_target_display_clock(
-+ struct bios_parser *bp,
-+ struct bp_display_clock_parameters *bp_params)
-+{
-+ if (!bp->cmd_tbl.compute_memore_engine_pll)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.compute_memore_engine_pll(bp, bp_params);
-+}
-+
-+enum bp_result dal_bios_parser_dvo_encoder_control(
-+ struct bios_parser *bp,
-+ struct bp_dvo_encoder_control *cntl)
-+{
-+ if (!bp->cmd_tbl.dvo_encoder_control)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.dvo_encoder_control(bp, cntl);
-+}
-+
-+enum bp_result dal_bios_parser_enable_crtc(
-+ struct bios_parser *bp,
-+ enum controller_id id,
-+ bool enable)
-+{
-+ if (!bp->cmd_tbl.enable_crtc)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.enable_crtc(bp, id, enable);
-+}
-+
-+enum bp_result dal_bios_parser_blank_crtc(
-+ struct bios_parser *bp,
-+ struct bp_blank_crtc_parameters *bp_params,
-+ bool blank)
-+{
-+ if (!bp->cmd_tbl.blank_crtc)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.blank_crtc(bp, bp_params, blank);
-+}
-+
-+enum bp_result dal_bios_parser_crtc_source_select(
-+ struct bios_parser *bp,
-+ struct bp_crtc_source_select *bp_params)
-+{
-+ if (!bp->cmd_tbl.select_crtc_source)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.select_crtc_source(bp, bp_params);
-+}
-+
-+enum bp_result dal_bios_parser_set_overscan(
-+ struct bios_parser *bp,
-+ struct bp_hw_crtc_overscan_parameters *bp_params)
-+{
-+
-+ if (!bp->cmd_tbl.set_crtc_overscan)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.set_crtc_overscan(bp, bp_params);
-+}
-+
-+enum bp_result dal_bios_parser_enable_memory_requests(
-+ struct bios_parser *bp,
-+ enum controller_id controller_id,
-+ bool enable)
-+{
-+ if (!bp->cmd_tbl.enable_crtc_mem_req)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.enable_crtc_mem_req(bp, controller_id, enable);
-+}
-+
-+enum bp_result dal_bios_parser_external_encoder_control(
-+ struct bios_parser *bp,
-+ struct bp_external_encoder_control *cntl)
-+{
-+ if (!bp->cmd_tbl.external_encoder_control)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.external_encoder_control(bp, cntl);
-+}
-+
-+enum bp_result dal_bios_parser_enable_disp_power_gating(
-+ struct bios_parser *bp,
-+ enum controller_id controller_id,
-+ enum bp_pipe_control_action action)
-+{
-+ if (!bp->cmd_tbl.enable_disp_power_gating)
-+ return BP_RESULT_FAILURE;
-+
-+ return bp->cmd_tbl.enable_disp_power_gating(bp, controller_id,
-+ action);
-+}
-+
-+bool dal_bios_parser_is_device_id_supported(
-+ struct bios_parser *bp,
-+ struct device_id id)
-+{
-+ uint32_t mask = get_support_mask_for_device_id(id);
-+
-+ return (le16_to_cpu(bp->object_info_tbl.v1_1->usDeviceSupport) & mask) != 0;
-+}
-+
-+enum bp_result dal_bios_parser_crt_control(
-+ struct bios_parser *bp,
-+ enum engine_id engine_id,
-+ bool enable,
-+ uint32_t pixel_clock)
-+{
-+ uint8_t standard;
-+
-+ if (!bp->cmd_tbl.dac1_encoder_control &&
-+ engine_id == ENGINE_ID_DACA)
-+ return BP_RESULT_FAILURE;
-+ if (!bp->cmd_tbl.dac2_encoder_control &&
-+ engine_id == ENGINE_ID_DACB)
-+ return BP_RESULT_FAILURE;
-+ /* validate params */
-+ switch (engine_id) {
-+ case ENGINE_ID_DACA:
-+ case ENGINE_ID_DACB:
-+ break;
-+ default:
-+ /* unsupported engine */
-+ return BP_RESULT_FAILURE;
-+ }
-+
-+ standard = ATOM_DAC1_PS2; /* == ATOM_DAC2_PS2 */
-+
-+ if (enable) {
-+ if (engine_id == ENGINE_ID_DACA) {
-+ bp->cmd_tbl.dac1_encoder_control(bp, enable,
-+ pixel_clock, standard);
-+ if (bp->cmd_tbl.dac1_output_control != NULL)
-+ bp->cmd_tbl.dac1_output_control(bp, enable);
-+ } else {
-+ bp->cmd_tbl.dac2_encoder_control(bp, enable,
-+ pixel_clock, standard);
-+ if (bp->cmd_tbl.dac2_output_control != NULL)
-+ bp->cmd_tbl.dac2_output_control(bp, enable);
-+ }
-+ } else {
-+ if (engine_id == ENGINE_ID_DACA) {
-+ if (bp->cmd_tbl.dac1_output_control != NULL)
-+ bp->cmd_tbl.dac1_output_control(bp, enable);
-+ bp->cmd_tbl.dac1_encoder_control(bp, enable,
-+ pixel_clock, standard);
-+ } else {
-+ if (bp->cmd_tbl.dac2_output_control != NULL)
-+ bp->cmd_tbl.dac2_output_control(bp, enable);
-+ bp->cmd_tbl.dac2_encoder_control(bp, enable,
-+ pixel_clock, standard);
-+ }
-+ }
-+
-+ return BP_RESULT_OK;
-+}
-+
-+static ATOM_HPD_INT_RECORD *get_hpd_record(struct bios_parser *bp,
-+ ATOM_OBJECT *object)
-+{
-+ ATOM_COMMON_RECORD_HEADER *header;
-+ uint32_t offset;
-+
-+ if (!object) {
-+ BREAK_TO_DEBUGGER(); /* Invalid object */
-+ return NULL;
-+ }
-+
-+ offset = le16_to_cpu(object->usRecordOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ for (;;) {
-+ header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
-+
-+ if (!header)
-+ return NULL;
-+
-+ if (LAST_RECORD_TYPE == header->ucRecordType ||
-+ !header->ucRecordSize)
-+ break;
-+
-+ if (ATOM_HPD_INT_RECORD_TYPE == header->ucRecordType
-+ && sizeof(ATOM_HPD_INT_RECORD) <= header->ucRecordSize)
-+ return (ATOM_HPD_INT_RECORD *) header;
-+
-+ offset += header->ucRecordSize;
-+ }
-+
-+ return NULL;
-+}
-+
-+/**
-+ * Get I2C information of input object id
-+ *
-+ * search all records to find the ATOM_I2C_RECORD_TYPE record IR
-+ */
-+static ATOM_I2C_RECORD *get_i2c_record(
-+ struct bios_parser *bp,
-+ ATOM_OBJECT *object)
-+{
-+ uint32_t offset;
-+ ATOM_COMMON_RECORD_HEADER *record_header;
-+
-+ if (!object) {
-+ BREAK_TO_DEBUGGER();
-+ /* Invalid object */
-+ return NULL;
-+ }
-+
-+ offset = le16_to_cpu(object->usRecordOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ for (;;) {
-+ record_header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
-+
-+ if (!record_header)
-+ return NULL;
-+
-+ if (LAST_RECORD_TYPE == record_header->ucRecordType ||
-+ 0 == record_header->ucRecordSize)
-+ break;
-+
-+ if (ATOM_I2C_RECORD_TYPE == record_header->ucRecordType &&
-+ sizeof(ATOM_I2C_RECORD) <=
-+ record_header->ucRecordSize) {
-+ return (ATOM_I2C_RECORD *)record_header;
-+ }
-+
-+ offset += record_header->ucRecordSize;
-+ }
-+
-+ return NULL;
-+}
-+
-+
-+static enum bp_result get_ss_info_from_ss_info_table(
-+ struct bios_parser *bp,
-+ uint32_t id,
-+ struct spread_spectrum_info *ss_info);
-+static enum bp_result get_ss_info_from_tbl(
-+ struct bios_parser *bp,
-+ uint32_t id,
-+ struct spread_spectrum_info *ss_info);
-+/**
-+ * dal_bios_parser_get_spread_spectrum_info
-+ * Get spread spectrum information from the ASIC_InternalSS_Info(ver 2.1 or
-+ * ver 3.1) or SS_Info table from the VBIOS. Currently ASIC_InternalSS_Info
-+ * ver 2.1 can co-exist with SS_Info table. Expect ASIC_InternalSS_Info ver 3.1,
-+ * there is only one entry for each signal /ss id. However, there is
-+ * no planning of supporting multiple spread Sprectum entry for EverGreen
-+ * @param [in] this
-+ * @param [in] signal, ASSignalType to be converted to info index
-+ * @param [in] index, number of entries that match the converted info index
-+ * @param [out] ss_info, sprectrum information structure,
-+ * @return Bios parser result code
-+ */
-+enum bp_result dal_bios_parser_get_spread_spectrum_info(
-+ struct bios_parser *bp,
-+ enum as_signal_type signal,
-+ uint32_t index,
-+ struct spread_spectrum_info *ss_info)
-+{
-+ enum bp_result result = BP_RESULT_UNSUPPORTED;
-+ uint32_t clk_id_ss = 0;
-+ ATOM_COMMON_TABLE_HEADER *header;
-+ struct atom_data_revision tbl_revision;
-+
-+ if (!ss_info) /* check for bad input */
-+ return BP_RESULT_BADINPUT;
-+ /* signal translation */
-+ clk_id_ss = signal_to_ss_id(signal);
-+
-+ if (!DATA_TABLES(ASIC_InternalSS_Info))
-+ if (!index)
-+ return get_ss_info_from_ss_info_table(bp, clk_id_ss,
-+ ss_info);
-+
-+ header = GET_IMAGE(ATOM_COMMON_TABLE_HEADER,
-+ DATA_TABLES(ASIC_InternalSS_Info));
-+ get_atom_data_table_revision(header, &tbl_revision);
-+
-+ switch (tbl_revision.major) {
-+ case 2:
-+ switch (tbl_revision.minor) {
-+ case 1:
-+ /* there can not be more then one entry for Internal
-+ * SS Info table version 2.1 */
-+ if (!index)
-+ return get_ss_info_from_tbl(bp, clk_id_ss,
-+ ss_info);
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+
-+ case 3:
-+ switch (tbl_revision.minor) {
-+ case 1:
-+ return get_ss_info_v3_1(bp, clk_id_ss, index, ss_info);
-+ default:
-+ break;
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+ /* there can not be more then one entry for SS Info table */
-+ return result;
-+}
-+
-+static enum bp_result get_ss_info_from_internal_ss_info_tbl_V2_1(
-+ struct bios_parser *bp,
-+ uint32_t id,
-+ struct spread_spectrum_info *info);
-+
-+/**
-+ * get_ss_info_from_table
-+ * Get spread sprectrum information from the ASIC_InternalSS_Info Ver 2.1 or
-+ * SS_Info table from the VBIOS
-+ * There can not be more than 1 entry for ASIC_InternalSS_Info Ver 2.1 or
-+ * SS_Info.
-+ *
-+ * @param this
-+ * @param id, spread sprectrum info index
-+ * @param pSSinfo, sprectrum information structure,
-+ * @return Bios parser result code
-+ */
-+static enum bp_result get_ss_info_from_tbl(
-+ struct bios_parser *bp,
-+ uint32_t id,
-+ struct spread_spectrum_info *ss_info)
-+{
-+ if (!ss_info) /* check for bad input, if ss_info is not NULL */
-+ return BP_RESULT_BADINPUT;
-+ /* for SS_Info table only support DP and LVDS */
-+ if (id == ASIC_INTERNAL_SS_ON_DP || id == ASIC_INTERNAL_SS_ON_LVDS)
-+ return get_ss_info_from_ss_info_table(bp, id, ss_info);
-+ else
-+ return get_ss_info_from_internal_ss_info_tbl_V2_1(bp, id,
-+ ss_info);
-+}
-+
-+/**
-+ * get_ss_info_from_internal_ss_info_tbl_V2_1
-+ * Get spread sprectrum information from the ASIC_InternalSS_Info table Ver 2.1
-+ * from the VBIOS
-+ * There will not be multiple entry for Ver 2.1
-+ *
-+ * @param id, spread sprectrum info index
-+ * @param pSSinfo, sprectrum information structure,
-+ * @return Bios parser result code
-+ */
-+static enum bp_result get_ss_info_from_internal_ss_info_tbl_V2_1(
-+ struct bios_parser *bp,
-+ uint32_t id,
-+ struct spread_spectrum_info *info)
-+{
-+ enum bp_result result = BP_RESULT_UNSUPPORTED;
-+ ATOM_ASIC_INTERNAL_SS_INFO_V2 *header;
-+ ATOM_ASIC_SS_ASSIGNMENT_V2 *tbl;
-+ uint32_t tbl_size, i;
-+
-+ if (!DATA_TABLES(ASIC_InternalSS_Info))
-+ return result;
-+
-+ header = GET_IMAGE(ATOM_ASIC_INTERNAL_SS_INFO_V2,
-+ DATA_TABLES(ASIC_InternalSS_Info));
-+
-+ dc_service_memset(info, 0, sizeof(struct spread_spectrum_info));
-+
-+ tbl_size = (le16_to_cpu(header->sHeader.usStructureSize)
-+ - sizeof(ATOM_COMMON_TABLE_HEADER))
-+ / sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2);
-+
-+ tbl = (ATOM_ASIC_SS_ASSIGNMENT_V2 *)
-+ &(header->asSpreadSpectrum[0]);
-+ for (i = 0; i < tbl_size; i++) {
-+ result = BP_RESULT_NORECORD;
-+
-+ if (tbl[i].ucClockIndication != (uint8_t)id)
-+ continue;
-+
-+ if (ATOM_EXTERNAL_SS_MASK
-+ & tbl[i].ucSpreadSpectrumMode) {
-+ info->type.EXTERNAL = true;
-+ }
-+ if (ATOM_SS_CENTRE_SPREAD_MODE_MASK
-+ & tbl[i].ucSpreadSpectrumMode) {
-+ info->type.CENTER_MODE = true;
-+ }
-+ info->type.STEP_AND_DELAY_INFO = false;
-+ /* convert [10KHz] into [KHz] */
-+ info->target_clock_range =
-+ le32_to_cpu(tbl[i].ulTargetClockRange) * 10;
-+ info->spread_spectrum_percentage =
-+ (uint32_t)le16_to_cpu(tbl[i].usSpreadSpectrumPercentage);
-+ info->spread_spectrum_range =
-+ (uint32_t)(le16_to_cpu(tbl[i].usSpreadRateIn10Hz) * 10);
-+ result = BP_RESULT_OK;
-+ break;
-+ }
-+
-+ return result;
-+
-+}
-+
-+/**
-+ * get_ss_info_from_ss_info_table
-+ * Get spread sprectrum information from the SS_Info table from the VBIOS
-+ * if the pointer to info is NULL, indicate the caller what to know the number
-+ * of entries that matches the id
-+ * for, the SS_Info table, there should not be more than 1 entry match.
-+ *
-+ * @param [in] id, spread sprectrum id
-+ * @param [out] pSSinfo, sprectrum information structure,
-+ * @return Bios parser result code
-+ */
-+static enum bp_result get_ss_info_from_ss_info_table(
-+ struct bios_parser *bp,
-+ uint32_t id,
-+ struct spread_spectrum_info *ss_info)
-+{
-+ enum bp_result result = BP_RESULT_UNSUPPORTED;
-+ ATOM_SPREAD_SPECTRUM_INFO *tbl;
-+ ATOM_COMMON_TABLE_HEADER *header;
-+ uint32_t table_size;
-+ uint32_t i;
-+ uint32_t id_local = SS_ID_UNKNOWN;
-+ struct atom_data_revision revision;
-+
-+ /* exist of the SS_Info table */
-+ /* check for bad input, pSSinfo can not be NULL */
-+ if (!DATA_TABLES(SS_Info) || !ss_info)
-+ return result;
-+
-+ header = GET_IMAGE(ATOM_COMMON_TABLE_HEADER, DATA_TABLES(SS_Info));
-+ get_atom_data_table_revision(header, &revision);
-+
-+ tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO, DATA_TABLES(SS_Info));
-+
-+ if (1 != revision.major || 2 > revision.minor)
-+ return result;
-+
-+ /* have to convert from Internal_SS format to SS_Info format */
-+ switch (id) {
-+ case ASIC_INTERNAL_SS_ON_DP:
-+ id_local = SS_ID_DP1;
-+ break;
-+ case ASIC_INTERNAL_SS_ON_LVDS:
-+ {
-+ struct embedded_panel_info panel_info;
-+
-+ if (dal_bios_parser_get_embedded_panel_info(bp, &panel_info)
-+ == BP_RESULT_OK)
-+ id_local = panel_info.ss_id;
-+ break;
-+ }
-+ default:
-+ break;
-+ }
-+
-+ if (id_local == SS_ID_UNKNOWN)
-+ return result;
-+
-+ table_size = (le16_to_cpu(tbl->sHeader.usStructureSize) -
-+ sizeof(ATOM_COMMON_TABLE_HEADER)) /
-+ sizeof(ATOM_SPREAD_SPECTRUM_ASSIGNMENT);
-+
-+ for (i = 0; i < table_size; i++) {
-+ if (id_local != (uint32_t)tbl->asSS_Info[i].ucSS_Id)
-+ continue;
-+
-+ dc_service_memset(ss_info, 0, sizeof(struct spread_spectrum_info));
-+
-+ if (ATOM_EXTERNAL_SS_MASK &
-+ tbl->asSS_Info[i].ucSpreadSpectrumType)
-+ ss_info->type.EXTERNAL = true;
-+
-+ if (ATOM_SS_CENTRE_SPREAD_MODE_MASK &
-+ tbl->asSS_Info[i].ucSpreadSpectrumType)
-+ ss_info->type.CENTER_MODE = true;
-+
-+ ss_info->type.STEP_AND_DELAY_INFO = true;
-+ ss_info->spread_spectrum_percentage =
-+ (uint32_t)le16_to_cpu(tbl->asSS_Info[i].usSpreadSpectrumPercentage);
-+ ss_info->step_and_delay_info.step = tbl->asSS_Info[i].ucSS_Step;
-+ ss_info->step_and_delay_info.delay =
-+ tbl->asSS_Info[i].ucSS_Delay;
-+ ss_info->step_and_delay_info.recommended_ref_div =
-+ tbl->asSS_Info[i].ucRecommendedRef_Div;
-+ ss_info->spread_spectrum_range =
-+ (uint32_t)tbl->asSS_Info[i].ucSS_Range * 10000;
-+
-+ /* there will be only one entry for each display type in SS_info
-+ * table */
-+ result = BP_RESULT_OK;
-+ break;
-+ }
-+
-+ return result;
-+}
-+static enum bp_result get_embedded_panel_info_v1_2(
-+ struct bios_parser *bp,
-+ struct embedded_panel_info *info);
-+static enum bp_result get_embedded_panel_info_v1_3(
-+ struct bios_parser *bp,
-+ struct embedded_panel_info *info);
-+
-+enum bp_result dal_bios_parser_get_embedded_panel_info(
-+ struct bios_parser *bp,
-+ struct embedded_panel_info *info)
-+{
-+ ATOM_COMMON_TABLE_HEADER *hdr;
-+
-+ if (!DATA_TABLES(LCD_Info))
-+ return BP_RESULT_FAILURE;
-+
-+ hdr = GET_IMAGE(ATOM_COMMON_TABLE_HEADER, DATA_TABLES(LCD_Info));
-+
-+ if (!hdr)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ switch (hdr->ucTableFormatRevision) {
-+ case 1:
-+ switch (hdr->ucTableContentRevision) {
-+ case 0:
-+ case 1:
-+ case 2:
-+ return get_embedded_panel_info_v1_2(bp, info);
-+ case 3:
-+ return get_embedded_panel_info_v1_3(bp, info);
-+ default:
-+ break;
-+ }
-+ default:
-+ break;
-+ }
-+
-+ return BP_RESULT_FAILURE;
-+}
-+
-+static enum bp_result get_embedded_panel_info_v1_2(
-+ struct bios_parser *bp,
-+ struct embedded_panel_info *info)
-+{
-+ ATOM_LVDS_INFO_V12 *lvds;
-+
-+ if (!info)
-+ return BP_RESULT_BADINPUT;
-+
-+ if (!DATA_TABLES(LVDS_Info))
-+ return BP_RESULT_UNSUPPORTED;
-+
-+ lvds =
-+ GET_IMAGE(ATOM_LVDS_INFO_V12, DATA_TABLES(LVDS_Info));
-+
-+ if (!lvds)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ if (1 != lvds->sHeader.ucTableFormatRevision
-+ || 2 > lvds->sHeader.ucTableContentRevision)
-+ return BP_RESULT_UNSUPPORTED;
-+
-+ dc_service_memset(info, 0, sizeof(struct embedded_panel_info));
-+
-+ /* We need to convert from 10KHz units into KHz units*/
-+ info->lcd_timing.pixel_clk =
-+ le16_to_cpu(lvds->sLCDTiming.usPixClk) * 10;
-+ /* usHActive does not include borders, according to VBIOS team*/
-+ info->lcd_timing.horizontal_addressable =
-+ le16_to_cpu(lvds->sLCDTiming.usHActive);
-+ /* usHBlanking_Time includes borders, so we should really be subtracting
-+ * borders duing this translation, but LVDS generally*/
-+ /* doesn't have borders, so we should be okay leaving this as is for
-+ * now. May need to revisit if we ever have LVDS with borders*/
-+ info->lcd_timing.horizontal_blanking_time =
-+ le16_to_cpu(lvds->sLCDTiming.usHBlanking_Time);
-+ /* usVActive does not include borders, according to VBIOS team*/
-+ info->lcd_timing.vertical_addressable =
-+ le16_to_cpu(lvds->sLCDTiming.usVActive);
-+ /* usVBlanking_Time includes borders, so we should really be subtracting
-+ * borders duing this translation, but LVDS generally*/
-+ /* doesn't have borders, so we should be okay leaving this as is for
-+ * now. May need to revisit if we ever have LVDS with borders*/
-+ info->lcd_timing.vertical_blanking_time =
-+ le16_to_cpu(lvds->sLCDTiming.usVBlanking_Time);
-+ info->lcd_timing.horizontal_sync_offset =
-+ le16_to_cpu(lvds->sLCDTiming.usHSyncOffset);
-+ info->lcd_timing.horizontal_sync_width =
-+ le16_to_cpu(lvds->sLCDTiming.usHSyncWidth);
-+ info->lcd_timing.vertical_sync_offset =
-+ le16_to_cpu(lvds->sLCDTiming.usVSyncOffset);
-+ info->lcd_timing.vertical_sync_width =
-+ le16_to_cpu(lvds->sLCDTiming.usVSyncWidth);
-+ info->lcd_timing.horizontal_border = lvds->sLCDTiming.ucHBorder;
-+ info->lcd_timing.vertical_border = lvds->sLCDTiming.ucVBorder;
-+ info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.HorizontalCutOff;
-+ info->lcd_timing.misc_info.H_SYNC_POLARITY =
-+ ~(uint32_t)
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.HSyncPolarity;
-+ info->lcd_timing.misc_info.V_SYNC_POLARITY =
-+ ~(uint32_t)
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.VSyncPolarity;
-+ info->lcd_timing.misc_info.VERTICAL_CUT_OFF =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.VerticalCutOff;
-+ info->lcd_timing.misc_info.H_REPLICATION_BY2 =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.H_ReplicationBy2;
-+ info->lcd_timing.misc_info.V_REPLICATION_BY2 =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.V_ReplicationBy2;
-+ info->lcd_timing.misc_info.COMPOSITE_SYNC =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.CompositeSync;
-+ info->lcd_timing.misc_info.INTERLACE =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.Interlace;
-+ info->lcd_timing.misc_info.DOUBLE_CLOCK =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.DoubleClock;
-+ info->ss_id = lvds->ucSS_Id;
-+
-+ {
-+ uint8_t rr = le16_to_cpu(lvds->usSupportedRefreshRate);
-+ /* Get minimum supported refresh rate*/
-+ if (SUPPORTED_LCD_REFRESHRATE_30Hz & rr)
-+ info->supported_rr.REFRESH_RATE_30HZ = 1;
-+ else if (SUPPORTED_LCD_REFRESHRATE_40Hz & rr)
-+ info->supported_rr.REFRESH_RATE_40HZ = 1;
-+ else if (SUPPORTED_LCD_REFRESHRATE_48Hz & rr)
-+ info->supported_rr.REFRESH_RATE_48HZ = 1;
-+ else if (SUPPORTED_LCD_REFRESHRATE_50Hz & rr)
-+ info->supported_rr.REFRESH_RATE_50HZ = 1;
-+ else if (SUPPORTED_LCD_REFRESHRATE_60Hz & rr)
-+ info->supported_rr.REFRESH_RATE_60HZ = 1;
-+ }
-+
-+ /*Drr panel support can be reported by VBIOS*/
-+ if (LCDPANEL_CAP_DRR_SUPPORTED
-+ & lvds->ucLCDPanel_SpecialHandlingCap)
-+ info->drr_enabled = 1;
-+
-+ if (ATOM_PANEL_MISC_DUAL & lvds->ucLVDS_Misc)
-+ info->lcd_timing.misc_info.DOUBLE_CLOCK = true;
-+
-+ if (ATOM_PANEL_MISC_888RGB & lvds->ucLVDS_Misc)
-+ info->lcd_timing.misc_info.RGB888 = true;
-+
-+ info->lcd_timing.misc_info.GREY_LEVEL =
-+ (uint32_t) (ATOM_PANEL_MISC_GREY_LEVEL &
-+ lvds->ucLVDS_Misc) >> ATOM_PANEL_MISC_GREY_LEVEL_SHIFT;
-+
-+ if (ATOM_PANEL_MISC_SPATIAL & lvds->ucLVDS_Misc)
-+ info->lcd_timing.misc_info.SPATIAL = true;
-+
-+ if (ATOM_PANEL_MISC_TEMPORAL & lvds->ucLVDS_Misc)
-+ info->lcd_timing.misc_info.TEMPORAL = true;
-+
-+ if (ATOM_PANEL_MISC_API_ENABLED & lvds->ucLVDS_Misc)
-+ info->lcd_timing.misc_info.API_ENABLED = true;
-+
-+ return BP_RESULT_OK;
-+}
-+
-+static enum bp_result get_embedded_panel_info_v1_3(
-+ struct bios_parser *bp,
-+ struct embedded_panel_info *info)
-+{
-+ ATOM_LCD_INFO_V13 *lvds;
-+
-+ if (!info)
-+ return BP_RESULT_BADINPUT;
-+
-+ if (!DATA_TABLES(LCD_Info))
-+ return BP_RESULT_UNSUPPORTED;
-+
-+ lvds = GET_IMAGE(ATOM_LCD_INFO_V13, DATA_TABLES(LCD_Info));
-+
-+ if (!lvds)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ if (!((1 == lvds->sHeader.ucTableFormatRevision)
-+ && (3 <= lvds->sHeader.ucTableContentRevision)))
-+ return BP_RESULT_UNSUPPORTED;
-+
-+ dc_service_memset(info, 0, sizeof(struct embedded_panel_info));
-+
-+ /* We need to convert from 10KHz units into KHz units */
-+ info->lcd_timing.pixel_clk =
-+ le16_to_cpu(lvds->sLCDTiming.usPixClk) * 10;
-+ /* usHActive does not include borders, according to VBIOS team */
-+ info->lcd_timing.horizontal_addressable =
-+ le16_to_cpu(lvds->sLCDTiming.usHActive);
-+ /* usHBlanking_Time includes borders, so we should really be subtracting
-+ * borders duing this translation, but LVDS generally*/
-+ /* doesn't have borders, so we should be okay leaving this as is for
-+ * now. May need to revisit if we ever have LVDS with borders*/
-+ info->lcd_timing.horizontal_blanking_time =
-+ le16_to_cpu(lvds->sLCDTiming.usHBlanking_Time);
-+ /* usVActive does not include borders, according to VBIOS team*/
-+ info->lcd_timing.vertical_addressable =
-+ le16_to_cpu(lvds->sLCDTiming.usVActive);
-+ /* usVBlanking_Time includes borders, so we should really be subtracting
-+ * borders duing this translation, but LVDS generally*/
-+ /* doesn't have borders, so we should be okay leaving this as is for
-+ * now. May need to revisit if we ever have LVDS with borders*/
-+ info->lcd_timing.vertical_blanking_time =
-+ le16_to_cpu(lvds->sLCDTiming.usVBlanking_Time);
-+ info->lcd_timing.horizontal_sync_offset =
-+ le16_to_cpu(lvds->sLCDTiming.usHSyncOffset);
-+ info->lcd_timing.horizontal_sync_width =
-+ le16_to_cpu(lvds->sLCDTiming.usHSyncWidth);
-+ info->lcd_timing.vertical_sync_offset =
-+ le16_to_cpu(lvds->sLCDTiming.usVSyncOffset);
-+ info->lcd_timing.vertical_sync_width =
-+ le16_to_cpu(lvds->sLCDTiming.usVSyncWidth);
-+ info->lcd_timing.horizontal_border = lvds->sLCDTiming.ucHBorder;
-+ info->lcd_timing.vertical_border = lvds->sLCDTiming.ucVBorder;
-+ info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.HorizontalCutOff;
-+ info->lcd_timing.misc_info.H_SYNC_POLARITY =
-+ ~(uint32_t)
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.HSyncPolarity;
-+ info->lcd_timing.misc_info.V_SYNC_POLARITY =
-+ ~(uint32_t)
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.VSyncPolarity;
-+ info->lcd_timing.misc_info.VERTICAL_CUT_OFF =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.VerticalCutOff;
-+ info->lcd_timing.misc_info.H_REPLICATION_BY2 =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.H_ReplicationBy2;
-+ info->lcd_timing.misc_info.V_REPLICATION_BY2 =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.V_ReplicationBy2;
-+ info->lcd_timing.misc_info.COMPOSITE_SYNC =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.CompositeSync;
-+ info->lcd_timing.misc_info.INTERLACE =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.Interlace;
-+ info->lcd_timing.misc_info.DOUBLE_CLOCK =
-+ lvds->sLCDTiming.susModeMiscInfo.sbfAccess.DoubleClock;
-+ info->ss_id = lvds->ucSS_Id;
-+
-+ /* Drr panel support can be reported by VBIOS*/
-+ if (LCDPANEL_CAP_V13_DRR_SUPPORTED
-+ & lvds->ucLCDPanel_SpecialHandlingCap)
-+ info->drr_enabled = 1;
-+
-+ /* Get supported refresh rate*/
-+ if (info->drr_enabled == 1) {
-+ uint8_t min_rr =
-+ lvds->sRefreshRateSupport.ucMinRefreshRateForDRR;
-+ uint8_t rr = lvds->sRefreshRateSupport.ucSupportedRefreshRate;
-+
-+ if (min_rr != 0) {
-+ if (SUPPORTED_LCD_REFRESHRATE_30Hz & min_rr)
-+ info->supported_rr.REFRESH_RATE_30HZ = 1;
-+ else if (SUPPORTED_LCD_REFRESHRATE_40Hz & min_rr)
-+ info->supported_rr.REFRESH_RATE_40HZ = 1;
-+ else if (SUPPORTED_LCD_REFRESHRATE_48Hz & min_rr)
-+ info->supported_rr.REFRESH_RATE_48HZ = 1;
-+ else if (SUPPORTED_LCD_REFRESHRATE_50Hz & min_rr)
-+ info->supported_rr.REFRESH_RATE_50HZ = 1;
-+ else if (SUPPORTED_LCD_REFRESHRATE_60Hz & min_rr)
-+ info->supported_rr.REFRESH_RATE_60HZ = 1;
-+ } else {
-+ if (SUPPORTED_LCD_REFRESHRATE_30Hz & rr)
-+ info->supported_rr.REFRESH_RATE_30HZ = 1;
-+ else if (SUPPORTED_LCD_REFRESHRATE_40Hz & rr)
-+ info->supported_rr.REFRESH_RATE_40HZ = 1;
-+ else if (SUPPORTED_LCD_REFRESHRATE_48Hz & rr)
-+ info->supported_rr.REFRESH_RATE_48HZ = 1;
-+ else if (SUPPORTED_LCD_REFRESHRATE_50Hz & rr)
-+ info->supported_rr.REFRESH_RATE_50HZ = 1;
-+ else if (SUPPORTED_LCD_REFRESHRATE_60Hz & rr)
-+ info->supported_rr.REFRESH_RATE_60HZ = 1;
-+ }
-+ }
-+
-+ if (ATOM_PANEL_MISC_V13_DUAL & lvds->ucLCD_Misc)
-+ info->lcd_timing.misc_info.DOUBLE_CLOCK = true;
-+
-+ if (ATOM_PANEL_MISC_V13_8BIT_PER_COLOR & lvds->ucLCD_Misc)
-+ info->lcd_timing.misc_info.RGB888 = true;
-+
-+ info->lcd_timing.misc_info.GREY_LEVEL =
-+ (uint32_t) (ATOM_PANEL_MISC_V13_GREY_LEVEL &
-+ lvds->ucLCD_Misc) >> ATOM_PANEL_MISC_V13_GREY_LEVEL_SHIFT;
-+
-+ return BP_RESULT_OK;
-+}
-+
-+/**
-+ * dal_bios_parser_get_encoder_cap_info
-+ *
-+ * @brief
-+ * Get encoder capability information of input object id
-+ *
-+ * @param object_id, Object id
-+ * @param object_id, encoder cap information structure
-+ *
-+ * @return Bios parser result code
-+ *
-+ */
-+enum bp_result dal_bios_parser_get_encoder_cap_info(
-+ struct bios_parser *bp,
-+ struct graphics_object_id object_id,
-+ struct bp_encoder_cap_info *info)
-+{
-+ ATOM_OBJECT *object;
-+ ATOM_ENCODER_CAP_RECORD *record = NULL;
-+
-+ if (!info)
-+ return BP_RESULT_BADINPUT;
-+
-+ object = get_bios_object(bp, object_id);
-+
-+ if (!object)
-+ return BP_RESULT_BADINPUT;
-+
-+ record = get_encoder_cap_record(bp, object);
-+ if (!record)
-+ return BP_RESULT_NORECORD;
-+
-+ info->DP_HBR2_CAP = record->usHBR2Cap;
-+ info->DP_HBR2_EN = record->usHBR2En;
-+ return BP_RESULT_OK;
-+}
-+
-+/**
-+ * get_encoder_cap_record
-+ *
-+ * @brief
-+ * Get encoder cap record for the object
-+ *
-+ * @param object, ATOM object
-+ *
-+ * @return atom encoder cap record
-+ *
-+ * @note
-+ * search all records to find the ATOM_ENCODER_CAP_RECORD record
-+ */
-+static ATOM_ENCODER_CAP_RECORD *get_encoder_cap_record(
-+ struct bios_parser *bp,
-+ ATOM_OBJECT *object)
-+{
-+ ATOM_COMMON_RECORD_HEADER *header;
-+ uint32_t offset;
-+
-+ if (!object) {
-+ BREAK_TO_DEBUGGER(); /* Invalid object */
-+ return NULL;
-+ }
-+
-+ offset = le16_to_cpu(object->usRecordOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ for (;;) {
-+ header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
-+
-+ if (!header)
-+ return NULL;
-+
-+ offset += header->ucRecordSize;
-+
-+ if (LAST_RECORD_TYPE == header->ucRecordType ||
-+ !header->ucRecordSize)
-+ break;
-+
-+ if (ATOM_ENCODER_CAP_RECORD_TYPE != header->ucRecordType)
-+ continue;
-+
-+ if (sizeof(ATOM_ENCODER_CAP_RECORD) <= header->ucRecordSize)
-+ return (ATOM_ENCODER_CAP_RECORD *)header;
-+ }
-+
-+ return NULL;
-+}
-+
-+/**
-+ * dal_bios_parser_get_din_connector_info
-+ * @brief
-+ * Get GPIO record for the DIN connector, this GPIO tells whether there is a
-+ * CV dumb dongle
-+ * attached to the DIN connector to perform load detection for the the
-+ * appropriate signal
-+ *
-+ * @param id - DIN connector object id
-+ * @param info - GPIO record infor
-+ * @return Bios parser result code
-+ */
-+enum bp_result dal_bios_parser_get_din_connector_info(
-+ struct bios_parser *bp,
-+ struct graphics_object_id id,
-+ struct din_connector_info *info)
-+{
-+ ATOM_COMMON_RECORD_HEADER *header;
-+ ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD *record = NULL;
-+ ATOM_OBJECT *object;
-+ uint32_t offset;
-+ enum bp_result result = BP_RESULT_NORECORD;
-+
-+ /* no output buffer provided */
-+ if (!info) {
-+ BREAK_TO_DEBUGGER(); /* Invalid output buffer */
-+ return BP_RESULT_BADINPUT;
-+ }
-+
-+ object = get_bios_object(bp, id);
-+ if (!object) {
-+ BREAK_TO_DEBUGGER(); /* Invalid object id */;
-+ return BP_RESULT_BADINPUT;
-+ }
-+
-+ offset = le16_to_cpu(object->usRecordOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ for (;;) {
-+ header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
-+
-+ if (!header) {
-+ result = BP_RESULT_BADBIOSTABLE;
-+ break;
-+ }
-+
-+ offset += header->ucRecordSize;
-+
-+ /* get out of the loop if no more records */
-+ if (LAST_RECORD_TYPE == header->ucRecordType ||
-+ !header->ucRecordSize)
-+ break;
-+
-+ if (ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD_TYPE !=
-+ header->ucRecordType)
-+ continue;
-+
-+ if (sizeof(ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD)
-+ > header->ucRecordSize)
-+ continue;
-+
-+ record = (ATOM_CONNECTOR_CVTV_SHARE_DIN_RECORD *)header;
-+ result = BP_RESULT_OK;
-+ break;
-+ }
-+
-+ /* return if the record not found */
-+ if (result != BP_RESULT_OK)
-+ return result;
-+
-+ info->gpio_id = record->ucGPIOID;
-+ info->gpio_tv_active_state = (record->ucTVActiveState != 0);
-+
-+ return result;
-+}
-+
-+static uint32_t get_ss_entry_number(
-+ struct bios_parser *bp,
-+ uint32_t id);
-+static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_v2_1(
-+ struct bios_parser *bp,
-+ uint32_t id);
-+static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_V3_1(
-+ struct bios_parser *bp,
-+ uint32_t id);
-+static uint32_t get_ss_entry_number_from_ss_info_tbl(
-+ struct bios_parser *bp,
-+ uint32_t id);
-+
-+/**
-+ * BiosParserObject::GetNumberofSpreadSpectrumEntry
-+ * Get Number of SpreadSpectrum Entry from the ASIC_InternalSS_Info table from
-+ * the VBIOS that match the SSid (to be converted from signal)
-+ *
-+ * @param[in] signal, ASSignalType to be converted to SSid
-+ * @return number of SS Entry that match the signal
-+ */
-+uint32_t dal_bios_parser_get_ss_entry_number(
-+ struct bios_parser *bp,
-+ enum as_signal_type signal)
-+{
-+ uint32_t ss_id = 0;
-+ ATOM_COMMON_TABLE_HEADER *header;
-+ struct atom_data_revision revision;
-+
-+ ss_id = signal_to_ss_id(signal);
-+
-+ if (!DATA_TABLES(ASIC_InternalSS_Info))
-+ return get_ss_entry_number_from_ss_info_tbl(bp, ss_id);
-+
-+ header = GET_IMAGE(ATOM_COMMON_TABLE_HEADER,
-+ DATA_TABLES(ASIC_InternalSS_Info));
-+ get_atom_data_table_revision(header, &revision);
-+
-+ switch (revision.major) {
-+ case 2:
-+ switch (revision.minor) {
-+ case 1:
-+ return get_ss_entry_number(bp, ss_id);
-+ default:
-+ break;
-+ }
-+ break;
-+ case 3:
-+ switch (revision.minor) {
-+ case 1:
-+ return
-+ get_ss_entry_number_from_internal_ss_info_tbl_V3_1(
-+ bp, ss_id);
-+ default:
-+ break;
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+/**
-+ * get_ss_entry_number_from_ss_info_tbl
-+ * Get Number of spread spectrum entry from the SS_Info table from the VBIOS.
-+ *
-+ * @note There can only be one entry for each id for SS_Info Table
-+ *
-+ * @param [in] id, spread spectrum id
-+ * @return number of SS Entry that match the id
-+ */
-+static uint32_t get_ss_entry_number_from_ss_info_tbl(
-+ struct bios_parser *bp,
-+ uint32_t id)
-+{
-+ ATOM_SPREAD_SPECTRUM_INFO *tbl;
-+ ATOM_COMMON_TABLE_HEADER *header;
-+ uint32_t table_size;
-+ uint32_t i;
-+ uint32_t number = 0;
-+ uint32_t id_local = SS_ID_UNKNOWN;
-+ struct atom_data_revision revision;
-+
-+ /* SS_Info table exist */
-+ if (!DATA_TABLES(SS_Info))
-+ return number;
-+
-+ header = GET_IMAGE(ATOM_COMMON_TABLE_HEADER,
-+ DATA_TABLES(SS_Info));
-+ get_atom_data_table_revision(header, &revision);
-+
-+ tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO,
-+ DATA_TABLES(SS_Info));
-+
-+ if (1 != revision.major || 2 > revision.minor)
-+ return number;
-+
-+ /* have to convert from Internal_SS format to SS_Info format */
-+ switch (id) {
-+ case ASIC_INTERNAL_SS_ON_DP:
-+ id_local = SS_ID_DP1;
-+ break;
-+ case ASIC_INTERNAL_SS_ON_LVDS: {
-+ struct embedded_panel_info panel_info;
-+
-+ if (dal_bios_parser_get_embedded_panel_info(bp, &panel_info)
-+ == BP_RESULT_OK)
-+ id_local = panel_info.ss_id;
-+ break;
-+ }
-+ default:
-+ break;
-+ }
-+
-+ if (id_local == SS_ID_UNKNOWN)
-+ return number;
-+
-+ table_size = (le16_to_cpu(tbl->sHeader.usStructureSize) -
-+ sizeof(ATOM_COMMON_TABLE_HEADER)) /
-+ sizeof(ATOM_SPREAD_SPECTRUM_ASSIGNMENT);
-+
-+ for (i = 0; i < table_size; i++)
-+ if (id_local == (uint32_t)tbl->asSS_Info[i].ucSS_Id) {
-+ number = 1;
-+ break;
-+ }
-+
-+ return number;
-+}
-+
-+
-+/**
-+ * get_ss_entry_number
-+ * Get spread sprectrum information from the ASIC_InternalSS_Info Ver 2.1 or
-+ * SS_Info table from the VBIOS
-+ * There can not be more than 1 entry for ASIC_InternalSS_Info Ver 2.1 or
-+ * SS_Info.
-+ *
-+ * @param id, spread sprectrum info index
-+ * @return Bios parser result code
-+ */
-+static uint32_t get_ss_entry_number(struct bios_parser *bp, uint32_t id)
-+{
-+ if (id == ASIC_INTERNAL_SS_ON_DP || id == ASIC_INTERNAL_SS_ON_LVDS)
-+ return get_ss_entry_number_from_ss_info_tbl(bp, id);
-+
-+ return get_ss_entry_number_from_internal_ss_info_tbl_v2_1(bp, id);
-+}
-+
-+/**
-+ * get_ss_entry_number_from_internal_ss_info_tbl_v2_1
-+ * Get NUmber of spread sprectrum entry from the ASIC_InternalSS_Info table
-+ * Ver 2.1 from the VBIOS
-+ * There will not be multiple entry for Ver 2.1
-+ *
-+ * @param id, spread sprectrum info index
-+ * @return number of SS Entry that match the id
-+ */
-+static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_v2_1(
-+ struct bios_parser *bp,
-+ uint32_t id)
-+{
-+ ATOM_ASIC_INTERNAL_SS_INFO_V2 *header_include;
-+ ATOM_ASIC_SS_ASSIGNMENT_V2 *tbl;
-+ uint32_t size;
-+ uint32_t i;
-+
-+ if (!DATA_TABLES(ASIC_InternalSS_Info))
-+ return 0;
-+
-+ header_include = GET_IMAGE(ATOM_ASIC_INTERNAL_SS_INFO_V2,
-+ DATA_TABLES(ASIC_InternalSS_Info));
-+
-+ size = (le16_to_cpu(header_include->sHeader.usStructureSize)
-+ - sizeof(ATOM_COMMON_TABLE_HEADER))
-+ / sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2);
-+
-+ tbl = (ATOM_ASIC_SS_ASSIGNMENT_V2 *)
-+ &header_include->asSpreadSpectrum[0];
-+ for (i = 0; i < size; i++)
-+ if (tbl[i].ucClockIndication == (uint8_t)id)
-+ return 1;
-+
-+ return 0;
-+}
-+/**
-+ * get_ss_entry_number_from_internal_ss_info_table_V3_1
-+ * Get Number of SpreadSpectrum Entry from the ASIC_InternalSS_Info table of
-+ * the VBIOS that matches id
-+ *
-+ * @param[in] id, spread sprectrum id
-+ * @return number of SS Entry that match the id
-+ */
-+static uint32_t get_ss_entry_number_from_internal_ss_info_tbl_V3_1(
-+ struct bios_parser *bp,
-+ uint32_t id)
-+{
-+ uint32_t number = 0;
-+ ATOM_ASIC_INTERNAL_SS_INFO_V3 *header_include;
-+ ATOM_ASIC_SS_ASSIGNMENT_V3 *tbl;
-+ uint32_t size;
-+ uint32_t i;
-+
-+ if (!DATA_TABLES(ASIC_InternalSS_Info))
-+ return number;
-+
-+ header_include = GET_IMAGE(ATOM_ASIC_INTERNAL_SS_INFO_V3,
-+ DATA_TABLES(ASIC_InternalSS_Info));
-+ size = (le16_to_cpu(header_include->sHeader.usStructureSize) -
-+ sizeof(ATOM_COMMON_TABLE_HEADER)) /
-+ sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3);
-+
-+ tbl = (ATOM_ASIC_SS_ASSIGNMENT_V3 *)
-+ &header_include->asSpreadSpectrum[0];
-+
-+ for (i = 0; i < size; i++)
-+ if (tbl[i].ucClockIndication == (uint8_t)id)
-+ number++;
-+
-+ return number;
-+}
-+
-+static ATOM_FAKE_EDID_PATCH_RECORD *get_faked_edid_record(
-+ struct bios_parser *bp)
-+{
-+ uint32_t size;
-+ uint8_t *record;
-+ ATOM_LVDS_INFO_V12 *info;
-+
-+ if (!DATA_TABLES(LVDS_Info))
-+ return NULL;
-+
-+ info = GET_IMAGE(ATOM_LVDS_INFO_V12, DATA_TABLES(LVDS_Info));
-+
-+ if (!info)
-+ return NULL;
-+
-+ if (1 != info->sHeader.ucTableFormatRevision
-+ || 2 > info->sHeader.ucTableContentRevision)
-+ return NULL;
-+
-+ if (!le16_to_cpu(info->usExtInfoTableOffset))
-+ return NULL;
-+
-+ record = GET_IMAGE(uint8_t, DATA_TABLES(LVDS_Info)
-+ + le16_to_cpu(info->usExtInfoTableOffset));
-+
-+ if (!record)
-+ return NULL;
-+
-+ for (;;) {
-+ if (ATOM_RECORD_END_TYPE == *record)
-+ return NULL;
-+
-+ if (LCD_FAKE_EDID_PATCH_RECORD_TYPE == *record)
-+ break;
-+
-+ size = get_record_size(record);
-+
-+ if (!size)
-+ return NULL;
-+
-+ record += size;
-+ }
-+
-+ return (ATOM_FAKE_EDID_PATCH_RECORD *)record;
-+}
-+
-+enum bp_result dal_bios_parser_get_faked_edid_len(
-+ struct bios_parser *bp,
-+ uint32_t *len)
-+{
-+ ATOM_FAKE_EDID_PATCH_RECORD *edid_record = get_faked_edid_record(bp);
-+
-+ if (!edid_record)
-+ return BP_RESULT_NORECORD;
-+
-+ *len = get_edid_size(edid_record);
-+
-+ return BP_RESULT_OK;
-+}
-+
-+enum bp_result dal_bios_parser_get_faked_edid_buf(
-+ struct bios_parser *bp,
-+ uint8_t *buff,
-+ uint32_t len)
-+{
-+ ATOM_FAKE_EDID_PATCH_RECORD *edid_record = get_faked_edid_record(bp);
-+ uint32_t edid_size;
-+
-+ if (!edid_record)
-+ return BP_RESULT_NORECORD;
-+
-+ edid_size = get_edid_size(edid_record);
-+
-+ if (len < edid_size)
-+ return BP_RESULT_BADINPUT; /* buffer not big enough to fill */
-+
-+ dc_service_memmove(buff, &edid_record->ucFakeEDIDString, edid_size);
-+
-+ return BP_RESULT_OK;
-+}
-+
-+/**
-+ * dal_bios_parser_get_gpio_pin_info
-+ * Get GpioPin information of input gpio id
-+ *
-+ * @param gpio_id, GPIO ID
-+ * @param info, GpioPin information structure
-+ * @return Bios parser result code
-+ * @note
-+ * to get the GPIO PIN INFO, we need:
-+ * 1. get the GPIO_ID from other object table, see GetHPDInfo()
-+ * 2. in DATA_TABLE.GPIO_Pin_LUT, search all records, to get the registerA
-+ * offset/mask
-+ */
-+enum bp_result dal_bios_parser_get_gpio_pin_info(
-+ struct bios_parser *bp,
-+ uint32_t gpio_id,
-+ struct gpio_pin_info *info)
-+{
-+ ATOM_GPIO_PIN_LUT *header;
-+ uint32_t count = 0;
-+ uint32_t i = 0;
-+
-+ if (!DATA_TABLES(GPIO_Pin_LUT))
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ header = GET_IMAGE(ATOM_GPIO_PIN_LUT, DATA_TABLES(GPIO_Pin_LUT));
-+ if (!header)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ if (sizeof(ATOM_COMMON_TABLE_HEADER) + sizeof(ATOM_GPIO_PIN_LUT)
-+ > le16_to_cpu(header->sHeader.usStructureSize))
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ if (1 != header->sHeader.ucTableContentRevision)
-+ return BP_RESULT_UNSUPPORTED;
-+
-+ count = (le16_to_cpu(header->sHeader.usStructureSize)
-+ - sizeof(ATOM_COMMON_TABLE_HEADER))
-+ / sizeof(ATOM_GPIO_PIN_ASSIGNMENT);
-+ for (i = 0; i < count; ++i) {
-+ if (header->asGPIO_Pin[i].ucGPIO_ID != gpio_id)
-+ continue;
-+
-+ info->offset =
-+ (uint32_t) le16_to_cpu(header->asGPIO_Pin[i].usGpioPin_AIndex);
-+ info->offset_y = info->offset + 2;
-+ info->offset_en = info->offset + 1;
-+ info->offset_mask = info->offset - 1;
-+
-+ info->mask = (uint32_t) (1 <<
-+ header->asGPIO_Pin[i].ucGpioPinBitShift);
-+ info->mask_y = info->mask + 2;
-+ info->mask_en = info->mask + 1;
-+ info->mask_mask = info->mask - 1;
-+
-+ return BP_RESULT_OK;
-+ }
-+
-+ return BP_RESULT_NORECORD;
-+}
-+
-+/**
-+ * BiosParserObject::EnumEmbeddedPanelPatchMode
-+ * Get embedded panel patch mode
-+ *
-+ * @param index, mode index
-+ * @param info, embedded panel patch mode structure
-+ * @return Bios parser result code
-+ */
-+enum bp_result dal_bios_parser_enum_embedded_panel_patch_mode(
-+ struct bios_parser *bp,
-+ uint32_t index,
-+ struct embedded_panel_patch_mode *mode)
-+{
-+ uint32_t record_size;
-+ uint32_t record_index;
-+ uint8_t *record;
-+ ATOM_LVDS_INFO_V12 *info;
-+ ATOM_PATCH_RECORD_MODE *mode_record;
-+ ATOM_MASTER_LIST_OF_DATA_TABLES *list_of_tables;
-+
-+ if (!mode)
-+ return BP_RESULT_BADINPUT;
-+
-+ list_of_tables = &bp->master_data_tbl->ListOfDataTables;
-+ if (!list_of_tables->LVDS_Info)
-+ return BP_RESULT_UNSUPPORTED;
-+
-+ info = GET_IMAGE(ATOM_LVDS_INFO_V12, list_of_tables->LVDS_Info);
-+
-+ if (!info)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ if (1 != info->sHeader.ucTableFormatRevision
-+ || 2 > info->sHeader.ucTableContentRevision)
-+ return BP_RESULT_UNSUPPORTED;
-+
-+ if (!le16_to_cpu(info->usExtInfoTableOffset))
-+ return BP_RESULT_UNSUPPORTED;
-+
-+ record = GET_IMAGE(uint8_t, list_of_tables->LVDS_Info +
-+ le16_to_cpu(info->usExtInfoTableOffset));
-+
-+ if (!record)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ for (record_index = 0;;) {
-+ if (ATOM_RECORD_END_TYPE == *record)
-+ return BP_RESULT_NORECORD;
-+
-+ if (LCD_MODE_PATCH_RECORD_MODE_TYPE == *record) {
-+ if (record_index == index)
-+ break;
-+ record_index++;
-+ }
-+
-+ record_size = get_record_size(record);
-+
-+ if (!record_size)
-+ return BP_RESULT_NORECORD;
-+
-+ record += record_size;
-+ }
-+
-+ mode_record = (ATOM_PATCH_RECORD_MODE *) record;
-+
-+ mode->width = le16_to_cpu(mode_record->usHDisp);
-+ mode->height = le16_to_cpu(mode_record->usVDisp);
-+
-+ return BP_RESULT_OK;
-+}
-+
-+static enum bp_result get_gpio_i2c_info(struct bios_parser *bp,
-+ ATOM_I2C_RECORD *record,
-+ struct graphics_object_i2c_info *info)
-+{
-+ ATOM_GPIO_I2C_INFO *header;
-+ uint32_t count = 0;
-+
-+ if (!info)
-+ return BP_RESULT_BADINPUT;
-+
-+ /* get the GPIO_I2C info */
-+ if (!DATA_TABLES(GPIO_I2C_Info))
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ header = GET_IMAGE(ATOM_GPIO_I2C_INFO, DATA_TABLES(GPIO_I2C_Info));
-+ if (!header)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ if (sizeof(ATOM_COMMON_TABLE_HEADER) + sizeof(ATOM_GPIO_I2C_ASSIGMENT)
-+ > le16_to_cpu(header->sHeader.usStructureSize))
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ if (1 != header->sHeader.ucTableContentRevision)
-+ return BP_RESULT_UNSUPPORTED;
-+
-+ /* get data count */
-+ count = (le16_to_cpu(header->sHeader.usStructureSize)
-+ - sizeof(ATOM_COMMON_TABLE_HEADER))
-+ / sizeof(ATOM_GPIO_I2C_ASSIGMENT);
-+ if (count < record->sucI2cId.bfI2C_LineMux)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ /* get the GPIO_I2C_INFO */
-+ info->i2c_hw_assist = record->sucI2cId.bfHW_Capable;
-+ info->i2c_line = record->sucI2cId.bfI2C_LineMux;
-+ info->i2c_engine_id = record->sucI2cId.bfHW_EngineID;
-+ info->i2c_slave_address = record->ucI2CAddr;
-+
-+ info->gpio_info.clk_mask_register_index =
-+ le16_to_cpu(header->asGPIO_Info[info->i2c_line].usClkMaskRegisterIndex);
-+ info->gpio_info.clk_en_register_index =
-+ le16_to_cpu(header->asGPIO_Info[info->i2c_line].usClkEnRegisterIndex);
-+ info->gpio_info.clk_y_register_index =
-+ le16_to_cpu(header->asGPIO_Info[info->i2c_line].usClkY_RegisterIndex);
-+ info->gpio_info.clk_a_register_index =
-+ le16_to_cpu(header->asGPIO_Info[info->i2c_line].usClkA_RegisterIndex);
-+ info->gpio_info.data_mask_register_index =
-+ le16_to_cpu(header->asGPIO_Info[info->i2c_line].usDataMaskRegisterIndex);
-+ info->gpio_info.data_en_register_index =
-+ le16_to_cpu(header->asGPIO_Info[info->i2c_line].usDataEnRegisterIndex);
-+ info->gpio_info.data_y_register_index =
-+ le16_to_cpu(header->asGPIO_Info[info->i2c_line].usDataY_RegisterIndex);
-+ info->gpio_info.data_a_register_index =
-+ le16_to_cpu(header->asGPIO_Info[info->i2c_line].usDataA_RegisterIndex);
-+
-+ info->gpio_info.clk_mask_shift =
-+ header->asGPIO_Info[info->i2c_line].ucClkMaskShift;
-+ info->gpio_info.clk_en_shift =
-+ header->asGPIO_Info[info->i2c_line].ucClkEnShift;
-+ info->gpio_info.clk_y_shift =
-+ header->asGPIO_Info[info->i2c_line].ucClkY_Shift;
-+ info->gpio_info.clk_a_shift =
-+ header->asGPIO_Info[info->i2c_line].ucClkA_Shift;
-+ info->gpio_info.data_mask_shift =
-+ header->asGPIO_Info[info->i2c_line].ucDataMaskShift;
-+ info->gpio_info.data_en_shift =
-+ header->asGPIO_Info[info->i2c_line].ucDataEnShift;
-+ info->gpio_info.data_y_shift =
-+ header->asGPIO_Info[info->i2c_line].ucDataY_Shift;
-+ info->gpio_info.data_a_shift =
-+ header->asGPIO_Info[info->i2c_line].ucDataA_Shift;
-+
-+ return BP_RESULT_OK;
-+}
-+
-+static ATOM_OBJECT *get_bios_object(struct bios_parser *bp,
-+ struct graphics_object_id id)
-+{
-+ uint32_t offset;
-+ ATOM_OBJECT_TABLE *tbl;
-+ uint32_t i;
-+
-+ switch (id.type) {
-+ case OBJECT_TYPE_ENCODER:
-+ offset = le16_to_cpu(bp->object_info_tbl.v1_1->usEncoderObjectTableOffset);
-+ break;
-+
-+ case OBJECT_TYPE_CONNECTOR:
-+ offset = le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset);
-+ break;
-+
-+ case OBJECT_TYPE_ROUTER:
-+ offset = le16_to_cpu(bp->object_info_tbl.v1_1->usRouterObjectTableOffset);
-+ break;
-+
-+ case OBJECT_TYPE_GENERIC:
-+ if (bp->object_info_tbl.revision.minor < 3)
-+ return NULL;
-+ offset = le16_to_cpu(bp->object_info_tbl.v1_3->usMiscObjectTableOffset);
-+ break;
-+
-+ default:
-+ return NULL;
-+ }
-+
-+ offset += bp->object_info_tbl_offset;
-+
-+ tbl = GET_IMAGE(ATOM_OBJECT_TABLE, offset);
-+ if (!tbl)
-+ return NULL;
-+
-+ for (i = 0; i < tbl->ucNumberOfObjects; i++)
-+ if (dal_graphics_object_id_is_equal(id,
-+ object_id_from_bios_object_id(
-+ le16_to_cpu(tbl->asObjects[i].usObjectID))))
-+ return &tbl->asObjects[i];
-+
-+ return NULL;
-+}
-+
-+static uint32_t get_dest_obj_list(struct bios_parser *bp,
-+ ATOM_OBJECT *object, uint16_t **id_list)
-+{
-+ uint32_t offset;
-+ uint8_t *number;
-+
-+ if (!object) {
-+ BREAK_TO_DEBUGGER(); /* Invalid object id */
-+ return 0;
-+ }
-+
-+ offset = le16_to_cpu(object->usSrcDstTableOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ number = GET_IMAGE(uint8_t, offset);
-+ if (!number)
-+ return 0;
-+
-+ offset += sizeof(uint8_t);
-+ offset += sizeof(uint16_t) * (*number);
-+
-+ number = GET_IMAGE(uint8_t, offset);
-+ if ((!number) || (!*number))
-+ return 0;
-+
-+ offset += sizeof(uint8_t);
-+ *id_list = (uint16_t *)get_image(bp, offset,
-+ *number * sizeof(uint16_t));
-+
-+ if (!*id_list)
-+ return 0;
-+
-+ return *number;
-+}
-+
-+static uint32_t get_src_obj_list(struct bios_parser *bp, ATOM_OBJECT *object,
-+ uint16_t **id_list)
-+{
-+ uint32_t offset;
-+ uint8_t *number;
-+
-+ if (!object) {
-+ BREAK_TO_DEBUGGER(); /* Invalid object id */
-+ return 0;
-+ }
-+
-+ offset = le16_to_cpu(object->usSrcDstTableOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ number = GET_IMAGE(uint8_t, offset);
-+ if (!number)
-+ return 0;
-+
-+ offset += sizeof(uint8_t);
-+ *id_list = (uint16_t *)get_image(bp, offset,
-+ *number * sizeof(uint16_t));
-+
-+ if (!*id_list)
-+ return 0;
-+
-+ return *number;
-+}
-+
-+static uint32_t get_dst_number_from_object(struct bios_parser *bp,
-+ ATOM_OBJECT *object)
-+{
-+ uint32_t offset;
-+ uint8_t *number;
-+
-+ if (!object) {
-+ BREAK_TO_DEBUGGER(); /* Invalid encoder object id*/
-+ return 0;
-+ }
-+
-+ offset = le16_to_cpu(object->usSrcDstTableOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ number = GET_IMAGE(uint8_t, offset);
-+ if (!number)
-+ return 0;
-+
-+ offset += sizeof(uint8_t);
-+ offset += sizeof(uint16_t) * (*number);
-+
-+ number = GET_IMAGE(uint8_t, offset);
-+
-+ if (!number)
-+ return 0;
-+
-+ return *number;
-+}
-+
-+static uint8_t *get_image(struct bios_parser *bp,
-+ uint32_t offset,
-+ uint32_t size)
-+{
-+ if (bp->bios && offset + size < bp->bios_size)
-+ return bp->bios + offset;
-+ else
-+ return NULL;
-+}
-+
-+static uint32_t get_record_size(uint8_t *record)
-+{
-+ switch (*record) {
-+ case LCD_MODE_PATCH_RECORD_MODE_TYPE:
-+ return sizeof(ATOM_PATCH_RECORD_MODE);
-+
-+ case LCD_RTS_RECORD_TYPE:
-+ return sizeof(ATOM_LCD_RTS_RECORD);
-+
-+ case LCD_CAP_RECORD_TYPE:
-+ return sizeof(ATOM_LCD_MODE_CONTROL_CAP);
-+
-+ case LCD_FAKE_EDID_PATCH_RECORD_TYPE: {
-+ ATOM_FAKE_EDID_PATCH_RECORD *fake_record =
-+ (ATOM_FAKE_EDID_PATCH_RECORD *) record;
-+ uint32_t edid_size = get_edid_size(fake_record);
-+
-+ return sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + edid_size
-+ - sizeof(fake_record->ucFakeEDIDString);
-+ }
-+
-+ case LCD_PANEL_RESOLUTION_RECORD_TYPE:
-+ return sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD);
-+
-+ default:
-+ return 0;
-+ }
-+}
-+
-+static uint32_t get_edid_size(const ATOM_FAKE_EDID_PATCH_RECORD *edid)
-+{
-+ uint32_t length = edid->ucFakeEDIDLength;
-+
-+ if (length < 128)
-+ length = length * 128;
-+
-+ return length;
-+}
-+
-+static struct graphics_object_id object_id_from_bios_object_id(
-+ uint32_t bios_object_id)
-+{
-+ enum object_type type;
-+ enum object_enum_id enum_id;
-+ struct graphics_object_id go_id = { 0 };
-+
-+ type = object_type_from_bios_object_id(bios_object_id);
-+
-+ if (OBJECT_TYPE_UNKNOWN == type)
-+ return go_id;
-+
-+ enum_id = enum_id_from_bios_object_id(bios_object_id);
-+
-+ if (ENUM_ID_UNKNOWN == enum_id)
-+ return go_id;
-+
-+ go_id = dal_graphics_object_id_init(
-+ id_from_bios_object_id(type, bios_object_id), enum_id, type);
-+
-+ return go_id;
-+}
-+
-+static enum object_type object_type_from_bios_object_id(uint32_t bios_object_id)
-+{
-+ uint32_t bios_object_type = (bios_object_id & OBJECT_TYPE_MASK)
-+ >> OBJECT_TYPE_SHIFT;
-+ enum object_type object_type;
-+
-+ switch (bios_object_type) {
-+ case GRAPH_OBJECT_TYPE_GPU:
-+ object_type = OBJECT_TYPE_GPU;
-+ break;
-+ case GRAPH_OBJECT_TYPE_ENCODER:
-+ object_type = OBJECT_TYPE_ENCODER;
-+ break;
-+ case GRAPH_OBJECT_TYPE_CONNECTOR:
-+ object_type = OBJECT_TYPE_CONNECTOR;
-+ break;
-+ case GRAPH_OBJECT_TYPE_ROUTER:
-+ object_type = OBJECT_TYPE_ROUTER;
-+ break;
-+ case GRAPH_OBJECT_TYPE_GENERIC:
-+ object_type = OBJECT_TYPE_GENERIC;
-+ break;
-+ default:
-+ object_type = OBJECT_TYPE_UNKNOWN;
-+ break;
-+ }
-+
-+ return object_type;
-+}
-+
-+static enum object_enum_id enum_id_from_bios_object_id(uint32_t bios_object_id)
-+{
-+ uint32_t bios_enum_id =
-+ (bios_object_id & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
-+ enum object_enum_id id;
-+
-+ switch (bios_enum_id) {
-+ case GRAPH_OBJECT_ENUM_ID1:
-+ id = ENUM_ID_1;
-+ break;
-+ case GRAPH_OBJECT_ENUM_ID2:
-+ id = ENUM_ID_2;
-+ break;
-+ case GRAPH_OBJECT_ENUM_ID3:
-+ id = ENUM_ID_3;
-+ break;
-+ case GRAPH_OBJECT_ENUM_ID4:
-+ id = ENUM_ID_4;
-+ break;
-+ case GRAPH_OBJECT_ENUM_ID5:
-+ id = ENUM_ID_5;
-+ break;
-+ case GRAPH_OBJECT_ENUM_ID6:
-+ id = ENUM_ID_6;
-+ break;
-+ case GRAPH_OBJECT_ENUM_ID7:
-+ id = ENUM_ID_7;
-+ break;
-+ default:
-+ id = ENUM_ID_UNKNOWN;
-+ break;
-+ }
-+
-+ return id;
-+}
-+
-+static uint32_t id_from_bios_object_id(enum object_type type,
-+ uint32_t bios_object_id)
-+{
-+ switch (type) {
-+ case OBJECT_TYPE_GPU:
-+ return gpu_id_from_bios_object_id(bios_object_id);
-+ case OBJECT_TYPE_ENCODER:
-+ return (uint32_t)encoder_id_from_bios_object_id(bios_object_id);
-+ case OBJECT_TYPE_CONNECTOR:
-+ return (uint32_t)connector_id_from_bios_object_id(
-+ bios_object_id);
-+ case OBJECT_TYPE_GENERIC:
-+ return generic_id_from_bios_object_id(bios_object_id);
-+ default:
-+ return 0;
-+ }
-+}
-+
-+static enum connector_id connector_id_from_bios_object_id(
-+ uint32_t bios_object_id)
-+{
-+ uint32_t bios_connector_id = gpu_id_from_bios_object_id(bios_object_id);
-+
-+ enum connector_id id;
-+
-+ switch (bios_connector_id) {
-+ case CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I:
-+ id = CONNECTOR_ID_SINGLE_LINK_DVII;
-+ break;
-+ case CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I:
-+ id = CONNECTOR_ID_DUAL_LINK_DVII;
-+ break;
-+ case CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D:
-+ id = CONNECTOR_ID_SINGLE_LINK_DVID;
-+ break;
-+ case CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D:
-+ id = CONNECTOR_ID_DUAL_LINK_DVID;
-+ break;
-+ case CONNECTOR_OBJECT_ID_VGA:
-+ id = CONNECTOR_ID_VGA;
-+ break;
-+ case CONNECTOR_OBJECT_ID_HDMI_TYPE_A:
-+ id = CONNECTOR_ID_HDMI_TYPE_A;
-+ break;
-+ case CONNECTOR_OBJECT_ID_LVDS:
-+ id = CONNECTOR_ID_LVDS;
-+ break;
-+ case CONNECTOR_OBJECT_ID_PCIE_CONNECTOR:
-+ id = CONNECTOR_ID_PCIE;
-+ break;
-+ case CONNECTOR_OBJECT_ID_HARDCODE_DVI:
-+ id = CONNECTOR_ID_HARDCODE_DVI;
-+ break;
-+ case CONNECTOR_OBJECT_ID_DISPLAYPORT:
-+ id = CONNECTOR_ID_DISPLAY_PORT;
-+ break;
-+ case CONNECTOR_OBJECT_ID_eDP:
-+ id = CONNECTOR_ID_EDP;
-+ break;
-+ case CONNECTOR_OBJECT_ID_MXM:
-+ id = CONNECTOR_ID_MXM;
-+ break;
-+ default:
-+ id = CONNECTOR_ID_UNKNOWN;
-+ break;
-+ }
-+
-+ return id;
-+}
-+
-+static enum encoder_id encoder_id_from_bios_object_id(uint32_t bios_object_id)
-+{
-+ uint32_t bios_encoder_id = gpu_id_from_bios_object_id(bios_object_id);
-+ enum encoder_id id;
-+
-+ switch (bios_encoder_id) {
-+ case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-+ id = ENCODER_ID_INTERNAL_LVDS;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
-+ id = ENCODER_ID_INTERNAL_TMDS1;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_TMDS2:
-+ id = ENCODER_ID_INTERNAL_TMDS2;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_DAC1:
-+ id = ENCODER_ID_INTERNAL_DAC1;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-+ id = ENCODER_ID_INTERNAL_DAC2;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_SDVOA:
-+ id = ENCODER_ID_INTERNAL_SDVOA;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_SDVOB:
-+ id = ENCODER_ID_INTERNAL_SDVOB;
-+ break;
-+ case ENCODER_OBJECT_ID_SI170B:
-+ id = ENCODER_ID_EXTERNAL_SI170B;
-+ break;
-+ case ENCODER_OBJECT_ID_CH7303:
-+ id = ENCODER_ID_EXTERNAL_CH7303;
-+ break;
-+ case ENCODER_OBJECT_ID_CH7301:
-+ id = ENCODER_ID_EXTERNAL_CH7301;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_DVO1:
-+ id = ENCODER_ID_INTERNAL_DVO1;
-+ break;
-+ case ENCODER_OBJECT_ID_EXTERNAL_SDVOA:
-+ id = ENCODER_ID_EXTERNAL_SDVOA;
-+ break;
-+ case ENCODER_OBJECT_ID_EXTERNAL_SDVOB:
-+ id = ENCODER_ID_EXTERNAL_SDVOB;
-+ break;
-+ case ENCODER_OBJECT_ID_TITFP513:
-+ id = ENCODER_ID_EXTERNAL_TITFP513;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-+ id = ENCODER_ID_INTERNAL_LVTM1;
-+ break;
-+ case ENCODER_OBJECT_ID_VT1623:
-+ id = ENCODER_ID_EXTERNAL_VT1623;
-+ break;
-+ case ENCODER_OBJECT_ID_HDMI_SI1930:
-+ id = ENCODER_ID_EXTERNAL_SI1930;
-+ break;
-+ case ENCODER_OBJECT_ID_HDMI_INTERNAL:
-+ id = ENCODER_ID_INTERNAL_HDMI;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-+ id = ENCODER_ID_INTERNAL_KLDSCP_TMDS1;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-+ id = ENCODER_ID_INTERNAL_KLDSCP_DVO1;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-+ id = ENCODER_ID_INTERNAL_KLDSCP_DAC1;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-+ id = ENCODER_ID_INTERNAL_KLDSCP_DAC2;
-+ break;
-+ case ENCODER_OBJECT_ID_SI178:
-+ id = ENCODER_ID_EXTERNAL_SI178;
-+ break;
-+ case ENCODER_OBJECT_ID_MVPU_FPGA:
-+ id = ENCODER_ID_EXTERNAL_MVPU_FPGA;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_DDI:
-+ id = ENCODER_ID_INTERNAL_DDI;
-+ break;
-+ case ENCODER_OBJECT_ID_VT1625:
-+ id = ENCODER_ID_EXTERNAL_VT1625;
-+ break;
-+ case ENCODER_OBJECT_ID_HDMI_SI1932:
-+ id = ENCODER_ID_EXTERNAL_SI1932;
-+ break;
-+ case ENCODER_OBJECT_ID_DP_AN9801:
-+ id = ENCODER_ID_EXTERNAL_AN9801;
-+ break;
-+ case ENCODER_OBJECT_ID_DP_DP501:
-+ id = ENCODER_ID_EXTERNAL_DP501;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-+ id = ENCODER_ID_INTERNAL_UNIPHY;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-+ id = ENCODER_ID_INTERNAL_KLDSCP_LVTMA;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-+ id = ENCODER_ID_INTERNAL_UNIPHY1;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-+ id = ENCODER_ID_INTERNAL_UNIPHY2;
-+ break;
-+ case ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO:
-+ id = ENCODER_ID_EXTERNAL_GENERIC_DVO;
-+ break;
-+ case ENCODER_OBJECT_ID_ALMOND: /* ENCODER_OBJECT_ID_NUTMEG */
-+ id = ENCODER_ID_EXTERNAL_NUTMEG;
-+ break;
-+ case ENCODER_OBJECT_ID_TRAVIS:
-+ id = ENCODER_ID_EXTERNAL_TRAVIS;
-+ break;
-+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
-+ id = ENCODER_ID_INTERNAL_UNIPHY3;
-+ break;
-+ default:
-+ id = ENCODER_ID_UNKNOWN;
-+ break;
-+ }
-+
-+ return id;
-+}
-+
-+uint32_t gpu_id_from_bios_object_id(uint32_t bios_object_id)
-+{
-+ return (bios_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
-+}
-+
-+enum generic_id generic_id_from_bios_object_id(uint32_t bios_object_id)
-+{
-+ uint32_t bios_generic_id = gpu_id_from_bios_object_id(bios_object_id);
-+
-+ enum generic_id id;
-+
-+ switch (bios_generic_id) {
-+ case GENERIC_OBJECT_ID_MXM_OPM:
-+ id = GENERIC_ID_MXM_OPM;
-+ break;
-+ case GENERIC_OBJECT_ID_GLSYNC:
-+ id = GENERIC_ID_GLSYNC;
-+ break;
-+ case GENERIC_OBJECT_ID_STEREO_PIN:
-+ id = GENERIC_ID_STEREO;
-+ break;
-+ default:
-+ id = GENERIC_ID_UNKNOWN;
-+ break;
-+ }
-+
-+ return id;
-+}
-+
-+static struct device_id device_type_from_device_id(uint16_t device_id)
-+{
-+
-+ struct device_id result_device_id;
-+
-+ switch (device_id) {
-+ case ATOM_DEVICE_LCD1_SUPPORT:
-+ result_device_id.device_type = DEVICE_TYPE_LCD;
-+ result_device_id.enum_id = 1;
-+ break;
-+
-+ case ATOM_DEVICE_LCD2_SUPPORT:
-+ result_device_id.device_type = DEVICE_TYPE_LCD;
-+ result_device_id.enum_id = 2;
-+ break;
-+
-+ case ATOM_DEVICE_CRT1_SUPPORT:
-+ result_device_id.device_type = DEVICE_TYPE_CRT;
-+ result_device_id.enum_id = 1;
-+ break;
-+
-+ case ATOM_DEVICE_CRT2_SUPPORT:
-+ result_device_id.device_type = DEVICE_TYPE_CRT;
-+ result_device_id.enum_id = 2;
-+ break;
-+
-+ case ATOM_DEVICE_DFP1_SUPPORT:
-+ result_device_id.device_type = DEVICE_TYPE_DFP;
-+ result_device_id.enum_id = 1;
-+ break;
-+
-+ case ATOM_DEVICE_DFP2_SUPPORT:
-+ result_device_id.device_type = DEVICE_TYPE_DFP;
-+ result_device_id.enum_id = 2;
-+ break;
-+
-+ case ATOM_DEVICE_DFP3_SUPPORT:
-+ result_device_id.device_type = DEVICE_TYPE_DFP;
-+ result_device_id.enum_id = 3;
-+ break;
-+
-+ case ATOM_DEVICE_DFP4_SUPPORT:
-+ result_device_id.device_type = DEVICE_TYPE_DFP;
-+ result_device_id.enum_id = 4;
-+ break;
-+
-+ case ATOM_DEVICE_DFP5_SUPPORT:
-+ result_device_id.device_type = DEVICE_TYPE_DFP;
-+ result_device_id.enum_id = 5;
-+ break;
-+
-+ case ATOM_DEVICE_DFP6_SUPPORT:
-+ result_device_id.device_type = DEVICE_TYPE_DFP;
-+ result_device_id.enum_id = 6;
-+ break;
-+
-+ default:
-+ BREAK_TO_DEBUGGER(); /* Invalid device Id */
-+ result_device_id.device_type = DEVICE_TYPE_UNKNOWN;
-+ result_device_id.enum_id = 0;
-+ }
-+ return result_device_id;
-+}
-+
-+static void get_atom_data_table_revision(
-+ ATOM_COMMON_TABLE_HEADER *atom_data_tbl,
-+ struct atom_data_revision *tbl_revision)
-+{
-+ if (!tbl_revision)
-+ return;
-+
-+ /* initialize the revision to 0 which is invalid revision */
-+ tbl_revision->major = 0;
-+ tbl_revision->minor = 0;
-+
-+ if (!atom_data_tbl)
-+ return;
-+
-+ tbl_revision->major =
-+ (uint32_t) GET_DATA_TABLE_MAJOR_REVISION(atom_data_tbl);
-+ tbl_revision->minor =
-+ (uint32_t) GET_DATA_TABLE_MINOR_REVISION(atom_data_tbl);
-+}
-+
-+static uint32_t signal_to_ss_id(enum as_signal_type signal)
-+{
-+ uint32_t clk_id_ss = 0;
-+
-+ switch (signal) {
-+ case AS_SIGNAL_TYPE_DVI:
-+ clk_id_ss = ASIC_INTERNAL_SS_ON_TMDS;
-+ break;
-+ case AS_SIGNAL_TYPE_HDMI:
-+ clk_id_ss = ASIC_INTERNAL_SS_ON_HDMI;
-+ break;
-+ case AS_SIGNAL_TYPE_LVDS:
-+ clk_id_ss = ASIC_INTERNAL_SS_ON_LVDS;
-+ break;
-+ case AS_SIGNAL_TYPE_DISPLAY_PORT:
-+ clk_id_ss = ASIC_INTERNAL_SS_ON_DP;
-+ break;
-+ case AS_SIGNAL_TYPE_GPU_PLL:
-+ clk_id_ss = ASIC_INTERNAL_GPUPLL_SS;
-+ break;
-+ default:
-+ break;
-+ }
-+ return clk_id_ss;
-+}
-+
-+static uint32_t get_support_mask_for_device_id(struct device_id device_id)
-+{
-+ enum dal_device_type device_type = device_id.device_type;
-+ uint32_t enum_id = device_id.enum_id;
-+
-+ switch (device_type) {
-+ case DEVICE_TYPE_LCD:
-+ switch (enum_id) {
-+ case 1:
-+ return ATOM_DEVICE_LCD1_SUPPORT;
-+ case 2:
-+ return ATOM_DEVICE_LCD2_SUPPORT;
-+ default:
-+ break;
-+ }
-+ break;
-+ case DEVICE_TYPE_CRT:
-+ switch (enum_id) {
-+ case 1:
-+ return ATOM_DEVICE_CRT1_SUPPORT;
-+ case 2:
-+ return ATOM_DEVICE_CRT2_SUPPORT;
-+ default:
-+ break;
-+ }
-+ break;
-+ case DEVICE_TYPE_DFP:
-+ switch (enum_id) {
-+ case 1:
-+ return ATOM_DEVICE_DFP1_SUPPORT;
-+ case 2:
-+ return ATOM_DEVICE_DFP2_SUPPORT;
-+ case 3:
-+ return ATOM_DEVICE_DFP3_SUPPORT;
-+ case 4:
-+ return ATOM_DEVICE_DFP4_SUPPORT;
-+ case 5:
-+ return ATOM_DEVICE_DFP5_SUPPORT;
-+ case 6:
-+ return ATOM_DEVICE_DFP6_SUPPORT;
-+ default:
-+ break;
-+ }
-+ break;
-+ case DEVICE_TYPE_CV:
-+ switch (enum_id) {
-+ case 1:
-+ return ATOM_DEVICE_CV_SUPPORT;
-+ default:
-+ break;
-+ }
-+ break;
-+ case DEVICE_TYPE_TV:
-+ switch (enum_id) {
-+ case 1:
-+ return ATOM_DEVICE_TV1_SUPPORT;
-+ default:
-+ break;
-+ }
-+ break;
-+ default:
-+ break;
-+ };
-+
-+ /* Unidentified device ID, return empty support mask. */
-+ return 0;
-+}
-+
-+/**
-+* HwContext interface for writing MM registers
-+*/
-+
-+static bool i2c_read(
-+ struct bios_parser *bp,
-+ struct graphics_object_i2c_info *i2c_info,
-+ uint8_t *buffer,
-+ uint32_t length)
-+{
-+ struct ddc *ddc;
-+ uint8_t offset[2] = { 0, 0 };
-+ bool result = false;
-+ struct i2c_command cmd;
-+
-+ ddc = dal_adapter_service_obtain_ddc_from_i2c_info(bp->as, i2c_info);
-+
-+ if (!ddc)
-+ return result;
-+
-+ /*Using SW engine */
-+ cmd.engine = I2C_COMMAND_ENGINE_SW;
-+ cmd.speed = dal_adapter_service_get_sw_i2c_speed(bp->as);
-+
-+ {
-+ struct i2c_payload payloads[] = {
-+ {
-+ .address = i2c_info->i2c_slave_address >> 1,
-+ .data = offset,
-+ .length = sizeof(offset),
-+ .write = true
-+ },
-+ {
-+ .address = i2c_info->i2c_slave_address >> 1,
-+ .data = buffer,
-+ .length = length,
-+ .write = false
-+ }
-+ };
-+
-+ cmd.payloads = payloads;
-+ cmd.number_of_payloads = ARRAY_SIZE(payloads);
-+
-+ result = dal_i2caux_submit_i2c_command(
-+ dal_adapter_service_get_i2caux(bp->as),
-+ ddc,
-+ &cmd);
-+ }
-+
-+ dal_adapter_service_release_ddc(bp->as, ddc);
-+
-+ return result;
-+}
-+
-+/**
-+ * Read external display connection info table through i2c.
-+ * validate the GUID and checksum.
-+ *
-+ * @return enum bp_result whether all data was sucessfully read
-+ */
-+static enum bp_result get_ext_display_connection_info(
-+ struct bios_parser *bp,
-+ ATOM_OBJECT *opm_object,
-+ ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO *ext_display_connection_info_tbl)
-+{
-+ bool config_tbl_present = false;
-+ ATOM_I2C_RECORD *i2c_record = NULL;
-+ uint32_t i = 0;
-+
-+ if (opm_object == NULL)
-+ return BP_RESULT_BADINPUT;
-+
-+ i2c_record = get_i2c_record(bp, opm_object);
-+
-+ if (i2c_record != NULL) {
-+ ATOM_GPIO_I2C_INFO *gpio_i2c_header;
-+ struct graphics_object_i2c_info i2c_info;
-+
-+ gpio_i2c_header = GET_IMAGE(ATOM_GPIO_I2C_INFO,
-+ bp->master_data_tbl->ListOfDataTables.GPIO_I2C_Info);
-+
-+ if (NULL == gpio_i2c_header)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ if (get_gpio_i2c_info(bp, i2c_record, &i2c_info) !=
-+ BP_RESULT_OK)
-+ return BP_RESULT_BADBIOSTABLE;
-+
-+ if (i2c_read(
-+ bp,
-+ &i2c_info,
-+ (uint8_t *)ext_display_connection_info_tbl,
-+ sizeof(ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO))) {
-+ config_tbl_present = true;
-+ }
-+ }
-+
-+ /* Validate GUID */
-+ if (config_tbl_present)
-+ for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; i++) {
-+ if (ext_display_connection_info_tbl->ucGuid[i]
-+ != ext_display_connection_guid[i]) {
-+ config_tbl_present = false;
-+ break;
-+ }
-+ }
-+
-+ /* Validate checksum */
-+ if (config_tbl_present) {
-+ uint8_t check_sum = 0;
-+ uint8_t *buf =
-+ (uint8_t *)ext_display_connection_info_tbl;
-+
-+ for (i = 0; i < sizeof(ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO);
-+ i++) {
-+ check_sum += buf[i];
-+ }
-+
-+ if (check_sum != 0)
-+ config_tbl_present = false;
-+ }
-+
-+ if (config_tbl_present)
-+ return BP_RESULT_OK;
-+ else
-+ return BP_RESULT_FAILURE;
-+}
-+
-+/*
-+ * Gets the first device ID in the same group as the given ID for enumerating.
-+ * For instance, if any DFP device ID is passed, returns the device ID for DFP1.
-+ *
-+ * The first device ID in the same group as the passed device ID, or 0 if no
-+ * matching device group found.
-+ */
-+static uint32_t enum_first_device_id(uint32_t dev_id)
-+{
-+ /* Return the first in the group that this ID belongs to. */
-+ if (dev_id & ATOM_DEVICE_CRT_SUPPORT)
-+ return ATOM_DEVICE_CRT1_SUPPORT;
-+ else if (dev_id & ATOM_DEVICE_DFP_SUPPORT)
-+ return ATOM_DEVICE_DFP1_SUPPORT;
-+ else if (dev_id & ATOM_DEVICE_LCD_SUPPORT)
-+ return ATOM_DEVICE_LCD1_SUPPORT;
-+ else if (dev_id & ATOM_DEVICE_TV_SUPPORT)
-+ return ATOM_DEVICE_TV1_SUPPORT;
-+ else if (dev_id & ATOM_DEVICE_CV_SUPPORT)
-+ return ATOM_DEVICE_CV_SUPPORT;
-+
-+ /* No group found for this device ID. */
-+
-+ dal_error("%s: incorrect input %d\n", __func__, dev_id);
-+ /* No matching support flag for given device ID */
-+ return 0;
-+}
-+
-+/*
-+ * Gets the next device ID in the group for a given device ID.
-+ *
-+ * The current device ID being enumerated on.
-+ *
-+ * The next device ID in the group, or 0 if no device exists.
-+ */
-+static uint32_t enum_next_dev_id(uint32_t dev_id)
-+{
-+ /* Get next device ID in the group. */
-+ switch (dev_id) {
-+ case ATOM_DEVICE_CRT1_SUPPORT:
-+ return ATOM_DEVICE_CRT2_SUPPORT;
-+ case ATOM_DEVICE_LCD1_SUPPORT:
-+ return ATOM_DEVICE_LCD2_SUPPORT;
-+ case ATOM_DEVICE_DFP1_SUPPORT:
-+ return ATOM_DEVICE_DFP2_SUPPORT;
-+ case ATOM_DEVICE_DFP2_SUPPORT:
-+ return ATOM_DEVICE_DFP3_SUPPORT;
-+ case ATOM_DEVICE_DFP3_SUPPORT:
-+ return ATOM_DEVICE_DFP4_SUPPORT;
-+ case ATOM_DEVICE_DFP4_SUPPORT:
-+ return ATOM_DEVICE_DFP5_SUPPORT;
-+ case ATOM_DEVICE_DFP5_SUPPORT:
-+ return ATOM_DEVICE_DFP6_SUPPORT;
-+ }
-+
-+ /* Done enumerating through devices. */
-+ return 0;
-+}
-+
-+/*
-+ * Returns the new device tag record for patched BIOS object.
-+ *
-+ * [IN] pExtDisplayPath - External display path to copy device tag from.
-+ * [IN] deviceSupport - Bit vector for device ID support flags.
-+ * [OUT] pDeviceTag - Device tag structure to fill with patched data.
-+ *
-+ * True if a compatible device ID was found, false otherwise.
-+ */
-+static bool get_patched_device_tag(
-+ struct bios_parser *bp,
-+ EXT_DISPLAY_PATH *ext_display_path,
-+ uint32_t device_support,
-+ ATOM_CONNECTOR_DEVICE_TAG *device_tag)
-+{
-+ uint32_t dev_id;
-+ /* Use fallback behaviour if not supported. */
-+ if (!bp->remap_device_tags) {
-+ device_tag->ulACPIDeviceEnum =
-+ cpu_to_le32((uint32_t) le16_to_cpu(ext_display_path->usDeviceACPIEnum));
-+ device_tag->usDeviceID =
-+ cpu_to_le16(le16_to_cpu(ext_display_path->usDeviceTag));
-+ return true;
-+ }
-+
-+ /* Find the first unused in the same group. */
-+ dev_id = enum_first_device_id(le16_to_cpu(ext_display_path->usDeviceTag));
-+ while (dev_id != 0) {
-+ /* Assign this device ID if supported. */
-+ if ((device_support & dev_id) != 0) {
-+ device_tag->ulACPIDeviceEnum =
-+ cpu_to_le32((uint32_t) le16_to_cpu(ext_display_path->usDeviceACPIEnum));
-+ device_tag->usDeviceID = cpu_to_le16((USHORT) dev_id);
-+ return true;
-+ }
-+
-+ dev_id = enum_next_dev_id(dev_id);
-+ }
-+
-+ /* No compatible device ID found. */
-+ return false;
-+}
-+
-+/*
-+ * Adds a device tag to a BIOS object's device tag record if there is
-+ * matching device ID supported.
-+ *
-+ * pObject - Pointer to the BIOS object to add the device tag to.
-+ * pExtDisplayPath - Display path to retrieve base device ID from.
-+ * pDeviceSupport - Pointer to bit vector for supported device IDs.
-+ */
-+static void add_device_tag_from_ext_display_path(
-+ struct bios_parser *bp,
-+ ATOM_OBJECT *object,
-+ EXT_DISPLAY_PATH *ext_display_path,
-+ uint32_t *device_support)
-+{
-+ /* Get device tag record for object. */
-+ ATOM_CONNECTOR_DEVICE_TAG *device_tag = NULL;
-+ ATOM_CONNECTOR_DEVICE_TAG_RECORD *device_tag_record = NULL;
-+ enum bp_result result =
-+ dal_bios_parser_get_device_tag_record(
-+ bp, object, &device_tag_record);
-+
-+ if ((le16_to_cpu(ext_display_path->usDeviceTag) != CONNECTOR_OBJECT_ID_NONE)
-+ && (result == BP_RESULT_OK)) {
-+ uint8_t index;
-+
-+ if ((device_tag_record->ucNumberOfDevice == 1) &&
-+ (le16_to_cpu(device_tag_record->asDeviceTag[0].usDeviceID) == 0)) {
-+ /*Workaround bug in current VBIOS releases where
-+ * ucNumberOfDevice = 1 but there is no actual device
-+ * tag data. This w/a is temporary until the updated
-+ * VBIOS is distributed. */
-+ device_tag_record->ucNumberOfDevice =
-+ device_tag_record->ucNumberOfDevice - 1;
-+ }
-+
-+ /* Attempt to find a matching device ID. */
-+ index = device_tag_record->ucNumberOfDevice;
-+ device_tag = &device_tag_record->asDeviceTag[index];
-+ if (get_patched_device_tag(
-+ bp,
-+ ext_display_path,
-+ *device_support,
-+ device_tag)) {
-+ /* Update cached device support to remove assigned ID.
-+ */
-+ *device_support &= ~le16_to_cpu(device_tag->usDeviceID);
-+ device_tag_record->ucNumberOfDevice++;
-+ }
-+ }
-+}
-+
-+/*
-+ * Read out a single EXT_DISPLAY_PATH from the external display connection info
-+ * table. The specific entry in the table is determined by the enum_id passed
-+ * in.
-+ *
-+ * EXT_DISPLAY_PATH describing a single Configuration table entry
-+ */
-+
-+#define INVALID_CONNECTOR 0xffff
-+
-+static EXT_DISPLAY_PATH *get_ext_display_path_entry(
-+ ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO *config_table,
-+ uint32_t bios_object_id)
-+{
-+ EXT_DISPLAY_PATH *ext_display_path;
-+ uint32_t ext_display_path_index =
-+ ((bios_object_id & ENUM_ID_MASK) >> ENUM_ID_SHIFT) - 1;
-+
-+ if (ext_display_path_index >= MAX_NUMBER_OF_EXT_DISPLAY_PATH)
-+ return NULL;
-+
-+ ext_display_path = &config_table->sPath[ext_display_path_index];
-+
-+ if (le16_to_cpu(ext_display_path->usDeviceConnector) == INVALID_CONNECTOR)
-+ ext_display_path->usDeviceConnector = cpu_to_le16(0);
-+
-+ return ext_display_path;
-+}
-+
-+/*
-+ * Get AUX/DDC information of input object id
-+ *
-+ * search all records to find the ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE record
-+ * IR
-+ */
-+static ATOM_CONNECTOR_AUXDDC_LUT_RECORD *get_ext_connector_aux_ddc_lut_record(
-+ struct bios_parser *bp,
-+ ATOM_OBJECT *object)
-+{
-+ uint32_t offset;
-+ ATOM_COMMON_RECORD_HEADER *header;
-+
-+ if (!object) {
-+ BREAK_TO_DEBUGGER();
-+ /* Invalid object */
-+ return NULL;
-+ }
-+
-+ offset = le16_to_cpu(object->usRecordOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ for (;;) {
-+ header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
-+
-+ if (!header)
-+ return NULL;
-+
-+ if (LAST_RECORD_TYPE == header->ucRecordType ||
-+ 0 == header->ucRecordSize)
-+ break;
-+
-+ if (ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE ==
-+ header->ucRecordType &&
-+ sizeof(ATOM_CONNECTOR_AUXDDC_LUT_RECORD) <=
-+ header->ucRecordSize)
-+ return (ATOM_CONNECTOR_AUXDDC_LUT_RECORD *)(header);
-+
-+ offset += header->ucRecordSize;
-+ }
-+
-+ return NULL;
-+}
-+
-+/*
-+ * Get AUX/DDC information of input object id
-+ *
-+ * search all records to find the ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE record
-+ * IR
-+ */
-+static ATOM_CONNECTOR_HPDPIN_LUT_RECORD *get_ext_connector_hpd_pin_lut_record(
-+ struct bios_parser *bp,
-+ ATOM_OBJECT *object)
-+{
-+ uint32_t offset;
-+ ATOM_COMMON_RECORD_HEADER *header;
-+
-+ if (!object) {
-+ BREAK_TO_DEBUGGER();
-+ /* Invalid object */
-+ return NULL;
-+ }
-+
-+ offset = le16_to_cpu(object->usRecordOffset)
-+ + bp->object_info_tbl_offset;
-+
-+ for (;;) {
-+ header = GET_IMAGE(ATOM_COMMON_RECORD_HEADER, offset);
-+
-+ if (!header)
-+ return NULL;
-+
-+ if (LAST_RECORD_TYPE == header->ucRecordType ||
-+ 0 == header->ucRecordSize)
-+ break;
-+
-+ if (ATOM_CONNECTOR_HPDPIN_LUT_RECORD_TYPE ==
-+ header->ucRecordType &&
-+ sizeof(ATOM_CONNECTOR_HPDPIN_LUT_RECORD) <=
-+ header->ucRecordSize)
-+ return (ATOM_CONNECTOR_HPDPIN_LUT_RECORD *)header;
-+
-+ offset += header->ucRecordSize;
-+ }
-+
-+ return NULL;
-+}
-+
-+/*
-+ * Check whether we need to patch the VBIOS connector info table with
-+ * data from an external display connection info table. This is
-+ * necessary to support MXM boards with an OPM (output personality
-+ * module). With these designs, the VBIOS connector info table
-+ * specifies an MXM_CONNECTOR with a unique ID. The driver retrieves
-+ * the external connection info table through i2c and then looks up the
-+ * connector ID to find the real connector type (e.g. DFP1).
-+ *
-+ */
-+static enum bp_result patch_bios_image_from_ext_display_connection_info(
-+ struct bios_parser *bp)
-+{
-+ ATOM_OBJECT_TABLE *connector_tbl;
-+ uint32_t connector_tbl_offset;
-+ struct graphics_object_id object_id;
-+ ATOM_OBJECT *object;
-+ ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO ext_display_connection_info_tbl;
-+ EXT_DISPLAY_PATH *ext_display_path;
-+ ATOM_CONNECTOR_AUXDDC_LUT_RECORD *aux_ddc_lut_record = NULL;
-+ ATOM_I2C_RECORD *i2c_record = NULL;
-+ ATOM_CONNECTOR_HPDPIN_LUT_RECORD *hpd_pin_lut_record = NULL;
-+ ATOM_HPD_INT_RECORD *hpd_record = NULL;
-+ ATOM_OBJECT_TABLE *encoder_table;
-+ uint32_t encoder_table_offset;
-+ ATOM_OBJECT *opm_object = NULL;
-+ uint32_t i = 0;
-+ struct graphics_object_id opm_object_id =
-+ dal_graphics_object_id_init(
-+ GENERIC_ID_MXM_OPM,
-+ ENUM_ID_1,
-+ OBJECT_TYPE_GENERIC);
-+ ATOM_CONNECTOR_DEVICE_TAG_RECORD *dev_tag_record;
-+ uint32_t cached_device_support =
-+ le16_to_cpu(bp->object_info_tbl.v1_1->usDeviceSupport);
-+
-+ uint32_t dst_number;
-+ uint16_t *dst_object_id_list;
-+
-+ opm_object = get_bios_object(bp, opm_object_id);
-+ if (!opm_object)
-+ return BP_RESULT_UNSUPPORTED;
-+
-+ dc_service_memset(&ext_display_connection_info_tbl, 0,
-+ sizeof(ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO));
-+
-+ connector_tbl_offset = bp->object_info_tbl_offset
-+ + le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset);
-+ connector_tbl = GET_IMAGE(ATOM_OBJECT_TABLE, connector_tbl_offset);
-+
-+ /* Read Connector info table from EEPROM through i2c */
-+ if (get_ext_display_connection_info(
-+ bp,
-+ opm_object,
-+ &ext_display_connection_info_tbl) != BP_RESULT_OK) {
-+ if (bp->headless_no_opm) {
-+ /* Failed to read OPM, remove all non-CF connectors. */
-+ for (i = 0; i < connector_tbl->ucNumberOfObjects; ++i) {
-+ object = &connector_tbl->asObjects[i];
-+ object_id = object_id_from_bios_object_id(
-+ le16_to_cpu(object->usObjectID));
-+ if (OBJECT_TYPE_CONNECTOR == object_id.type)
-+ object->usObjectID = cpu_to_le16(0);
-+ }
-+
-+ return BP_RESULT_OK;
-+ }
-+
-+ dal_logger_write(bp->ctx->logger,
-+ LOG_MAJOR_BIOS,
-+ LOG_MINOR_BIOS_CMD_TABLE,
-+ "%s: Failed to read Connection Info Table", __func__);
-+ return BP_RESULT_UNSUPPORTED;
-+ }
-+
-+ /* Get pointer to AUX/DDC and HPD LUTs */
-+ aux_ddc_lut_record =
-+ get_ext_connector_aux_ddc_lut_record(bp, opm_object);
-+ hpd_pin_lut_record =
-+ get_ext_connector_hpd_pin_lut_record(bp, opm_object);
-+
-+ if ((aux_ddc_lut_record == NULL) || (hpd_pin_lut_record == NULL))
-+ return BP_RESULT_UNSUPPORTED;
-+
-+ /* Cache support bits for currently unmapped device types. */
-+ if (bp->remap_device_tags) {
-+ for (i = 0; i < connector_tbl->ucNumberOfObjects; ++i) {
-+ uint32_t j;
-+ /* Remove support for all non-MXM connectors. */
-+ object = &connector_tbl->asObjects[i];
-+ object_id = object_id_from_bios_object_id(
-+ le16_to_cpu(object->usObjectID));
-+ if ((OBJECT_TYPE_CONNECTOR != object_id.type) ||
-+ (CONNECTOR_ID_MXM == object_id.id))
-+ continue;
-+
-+ /* Remove support for all device tags. */
-+ if (dal_bios_parser_get_device_tag_record(
-+ bp, object, &dev_tag_record) != BP_RESULT_OK)
-+ continue;
-+
-+ for (j = 0; j < dev_tag_record->ucNumberOfDevice; ++j) {
-+ ATOM_CONNECTOR_DEVICE_TAG *device_tag =
-+ &dev_tag_record->asDeviceTag[j];
-+ cached_device_support &=
-+ ~le16_to_cpu(device_tag->usDeviceID);
-+ }
-+ }
-+ }
-+
-+ /* Find all MXM connector objects and patch them with connector info
-+ * from the external display connection info table. */
-+ for (i = 0; i < connector_tbl->ucNumberOfObjects; i++) {
-+ uint32_t j;
-+
-+ object = &connector_tbl->asObjects[i];
-+ object_id = object_id_from_bios_object_id(le16_to_cpu(object->usObjectID));
-+ if ((OBJECT_TYPE_CONNECTOR != object_id.type) ||
-+ (CONNECTOR_ID_MXM != object_id.id))
-+ continue;
-+
-+ /* Get the correct connection info table entry based on the enum
-+ * id. */
-+ ext_display_path = get_ext_display_path_entry(
-+ &ext_display_connection_info_tbl,
-+ le16_to_cpu(object->usObjectID));
-+ if (!ext_display_path)
-+ return BP_RESULT_FAILURE;
-+
-+ /* Patch device connector ID */
-+ object->usObjectID =
-+ cpu_to_le16(le16_to_cpu(ext_display_path->usDeviceConnector));
-+
-+ /* Patch device tag, ulACPIDeviceEnum. */
-+ add_device_tag_from_ext_display_path(
-+ bp,
-+ object,
-+ ext_display_path,
-+ &cached_device_support);
-+
-+ /* Patch HPD info */
-+ if (ext_display_path->ucExtHPDPINLutIndex <
-+ MAX_NUMBER_OF_EXT_HPDPIN_LUT_ENTRIES) {
-+ hpd_record = get_hpd_record(bp, object);
-+ if (hpd_record) {
-+ uint8_t index =
-+ ext_display_path->ucExtHPDPINLutIndex;
-+ hpd_record->ucHPDIntGPIOID =
-+ hpd_pin_lut_record->ucHPDPINMap[index];
-+ } else {
-+ BREAK_TO_DEBUGGER();
-+ /* Invalid hpd record */
-+ return BP_RESULT_FAILURE;
-+ }
-+ }
-+
-+ /* Patch I2C/AUX info */
-+ if (ext_display_path->ucExtHPDPINLutIndex <
-+ MAX_NUMBER_OF_EXT_AUXDDC_LUT_ENTRIES) {
-+ i2c_record = get_i2c_record(bp, object);
-+ if (i2c_record) {
-+ uint8_t index =
-+ ext_display_path->ucExtAUXDDCLutIndex;
-+ i2c_record->sucI2cId =
-+ aux_ddc_lut_record->ucAUXDDCMap[index];
-+ } else {
-+ BREAK_TO_DEBUGGER();
-+ /* Invalid I2C record */
-+ return BP_RESULT_FAILURE;
-+ }
-+ }
-+
-+ /* Merge with other MXM connectors that map to the same physical
-+ * connector. */
-+ for (j = i + 1;
-+ j < connector_tbl->ucNumberOfObjects; j++) {
-+ ATOM_OBJECT *next_object;
-+ struct graphics_object_id next_object_id;
-+ EXT_DISPLAY_PATH *next_ext_display_path;
-+
-+ next_object = &connector_tbl->asObjects[j];
-+ next_object_id = object_id_from_bios_object_id(
-+ le16_to_cpu(next_object->usObjectID));
-+
-+ if ((OBJECT_TYPE_CONNECTOR != next_object_id.type) &&
-+ (CONNECTOR_ID_MXM == next_object_id.id))
-+ continue;
-+
-+ next_ext_display_path = get_ext_display_path_entry(
-+ &ext_display_connection_info_tbl,
-+ le16_to_cpu(next_object->usObjectID));
-+
-+ if (next_ext_display_path == NULL)
-+ return BP_RESULT_FAILURE;
-+
-+ /* Merge if using same connector. */
-+ if ((le16_to_cpu(next_ext_display_path->usDeviceConnector) ==
-+ le16_to_cpu(ext_display_path->usDeviceConnector)) &&
-+ (le16_to_cpu(ext_display_path->usDeviceConnector) != 0)) {
-+ /* Clear duplicate connector from table. */
-+ next_object->usObjectID = cpu_to_le16(0);
-+ add_device_tag_from_ext_display_path(
-+ bp,
-+ object,
-+ ext_display_path,
-+ &cached_device_support);
-+ }
-+ }
-+ }
-+
-+ /* Find all encoders which have an MXM object as their destination.
-+ * Replace the MXM object with the real connector Id from the external
-+ * display connection info table */
-+
-+ encoder_table_offset = bp->object_info_tbl_offset
-+ + le16_to_cpu(bp->object_info_tbl.v1_1->usEncoderObjectTableOffset);
-+ encoder_table = GET_IMAGE(ATOM_OBJECT_TABLE, encoder_table_offset);
-+
-+ for (i = 0; i < encoder_table->ucNumberOfObjects; i++) {
-+ uint32_t j;
-+
-+ object = &encoder_table->asObjects[i];
-+
-+ dst_number = get_dest_obj_list(bp, object, &dst_object_id_list);
-+
-+ for (j = 0; j < dst_number; j++) {
-+ object_id = object_id_from_bios_object_id(
-+ dst_object_id_list[j]);
-+
-+ if ((OBJECT_TYPE_CONNECTOR != object_id.type) ||
-+ (CONNECTOR_ID_MXM != object_id.id))
-+ continue;
-+
-+ /* Get the correct connection info table entry based on
-+ * the enum id. */
-+ ext_display_path =
-+ get_ext_display_path_entry(
-+ &ext_display_connection_info_tbl,
-+ dst_object_id_list[j]);
-+
-+ if (ext_display_path == NULL)
-+ return BP_RESULT_FAILURE;
-+
-+ dst_object_id_list[j] =
-+ le16_to_cpu(ext_display_path->usDeviceConnector);
-+ }
-+ }
-+
-+ return BP_RESULT_OK;
-+}
-+
-+/*
-+ * Check whether we need to patch the VBIOS connector info table with
-+ * data from an external display connection info table. This is
-+ * necessary to support MXM boards with an OPM (output personality
-+ * module). With these designs, the VBIOS connector info table
-+ * specifies an MXM_CONNECTOR with a unique ID. The driver retrieves
-+ * the external connection info table through i2c and then looks up the
-+ * connector ID to find the real connector type (e.g. DFP1).
-+ *
-+ */
-+
-+static void process_ext_display_connection_info(struct bios_parser *bp)
-+{
-+ ATOM_OBJECT_TABLE *connector_tbl;
-+ uint32_t connector_tbl_offset;
-+ struct graphics_object_id object_id;
-+ ATOM_OBJECT *object;
-+ bool mxm_connector_found = false;
-+ bool null_entry_found = false;
-+ uint32_t i = 0;
-+
-+ connector_tbl_offset = bp->object_info_tbl_offset +
-+ le16_to_cpu(bp->object_info_tbl.v1_1->usConnectorObjectTableOffset);
-+ connector_tbl = GET_IMAGE(ATOM_OBJECT_TABLE, connector_tbl_offset);
-+
-+ /* Look for MXM connectors to determine whether we need patch the VBIOS
-+ * connector info table. Look for null entries to determine whether we
-+ * need to compact connector table. */
-+ for (i = 0; i < connector_tbl->ucNumberOfObjects; i++) {
-+ object = &connector_tbl->asObjects[i];
-+ object_id = object_id_from_bios_object_id(le16_to_cpu(object->usObjectID));
-+
-+ if ((OBJECT_TYPE_CONNECTOR == object_id.type) &&
-+ (CONNECTOR_ID_MXM == object_id.id)) {
-+ /* Once we found MXM connector - we can break */
-+ mxm_connector_found = true;
-+ break;
-+ } else if (OBJECT_TYPE_CONNECTOR != object_id.type) {
-+ /* We need to continue looping - to check if MXM
-+ * connector present */
-+ null_entry_found = true;
-+ }
-+ }
-+
-+ /* Patch BIOS image */
-+ if (mxm_connector_found || null_entry_found) {
-+ uint32_t connectors_num = 0;
-+ uint8_t *original_bios;
-+ /* Step 1: Replace bios image with the new copy which will be
-+ * patched */
-+ bp->bios_local_image = dc_service_alloc(bp->ctx, bp->bios_size);
-+ if (bp->bios_local_image == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ /* Failed to alloc bp->bios_local_image */
-+ return;
-+ }
-+
-+ dc_service_memmove(bp->bios_local_image, bp->bios, bp->bios_size);
-+ original_bios = bp->bios;
-+ bp->bios = bp->bios_local_image;
-+ connector_tbl =
-+ GET_IMAGE(ATOM_OBJECT_TABLE, connector_tbl_offset);
-+
-+ /* Step 2: (only if MXM connector found) Patch BIOS image with
-+ * info from external module */
-+ if (mxm_connector_found &&
-+ patch_bios_image_from_ext_display_connection_info(bp) !=
-+ BP_RESULT_OK) {
-+ /* Patching the bios image has failed. We will copy
-+ * again original image provided and afterwards
-+ * only remove null entries */
-+ dc_service_memmove(
-+ bp->bios_local_image,
-+ original_bios,
-+ bp->bios_size);
-+ }
-+
-+ /* Step 3: Compact connector table (remove null entries, valid
-+ * entries moved to beginning) */
-+ for (i = 0; i < connector_tbl->ucNumberOfObjects; i++) {
-+ object = &connector_tbl->asObjects[i];
-+ object_id = object_id_from_bios_object_id(
-+ le16_to_cpu(object->usObjectID));
-+
-+ if (OBJECT_TYPE_CONNECTOR != object_id.type)
-+ continue;
-+
-+ if (i != connectors_num) {
-+ dc_service_memmove(
-+ &connector_tbl->
-+ asObjects[connectors_num],
-+ object,
-+ sizeof(ATOM_OBJECT));
-+ }
-+ ++connectors_num;
-+ }
-+ connector_tbl->ucNumberOfObjects = (uint8_t)connectors_num;
-+ }
-+}
-+
-+void dal_bios_parser_post_init(struct bios_parser *bp)
-+{
-+ process_ext_display_connection_info(bp);
-+}
-+
-+bool dal_bios_parser_is_accelerated_mode(
-+ struct bios_parser *bp)
-+{
-+#ifdef CONFIG_DRM_AMD_DAL_VBIOS_PRESENT
-+ return bp->bios_helper->is_accelerated_mode(
-+ bp->ctx);
-+#else
-+ dal_logger_write(bp->ctx->logger,
-+ LOG_MAJOR_BIOS,
-+ LOG_MINOR_BIOS_CMD_TABLE,
-+ "%s: VBIOS is not supported", __func__);
-+ return false;
-+#endif
-+}
-+
-+/**
-+* dal_bios_parser_set_scratch_connected
-+*
-+* @brief
-+* update VBIOS scratch register about connected displays
-+*
-+* @param
-+* bool - update scratch register or just prepare info to be updated
-+* bool - connection state
-+* const ConnectorDeviceTagInfo* - pointer to device type and enum ID
-+*/
-+void dal_bios_parser_set_scratch_connected(
-+ struct bios_parser *bp,
-+ struct graphics_object_id connector_id,
-+ bool connected,
-+ const struct connector_device_tag_info *device_tag)
-+{
-+#ifdef CONFIG_DRM_AMD_DAL_VBIOS_PRESENT
-+ bp->bios_helper->set_scratch_connected(
-+ bp->ctx,
-+ connector_id, connected, device_tag);
-+#else
-+ dal_logger_write(bp->ctx->logger,
-+ LOG_MAJOR_BIOS,
-+ LOG_MINOR_BIOS_CMD_TABLE,
-+ "%s: VBIOS is not supported", __func__);
-+#endif
-+}
-+
-+/**
-+* dal_bios_parser_set_scratch_critical_state
-+*
-+* @brief
-+* update critical state bit in VBIOS scratch register
-+*
-+* @param
-+* bool - to set or reset state
-+*/
-+void dal_bios_parser_set_scratch_critical_state(
-+ struct bios_parser *bp,
-+ bool state)
-+{
-+#ifdef CONFIG_DRM_AMD_DAL_VBIOS_PRESENT
-+ bp->bios_helper->set_scratch_critical_state(
-+ bp->ctx, state);
-+#else
-+ dal_logger_write(bp->ctx->logger,
-+ LOG_MAJOR_BIOS,
-+ LOG_MINOR_BIOS_CMD_TABLE,
-+ "%s: VBIOS is not supported", __func__);
-+#endif
-+}
-+
-+void dal_bios_parser_set_scratch_acc_mode_change(
-+ struct bios_parser *bp)
-+{
-+#ifdef CONFIG_DRM_AMD_DAL_VBIOS_PRESENT
-+ bp->bios_helper->set_scratch_acc_mode_change(
-+ bp->ctx);
-+#else
-+ dal_logger_write(bp->ctx->logger,
-+ LOG_MAJOR_BIOS,
-+ LOG_MINOR_BIOS_CMD_TABLE,
-+ "%s: VBIOS is not supported", __func__);
-+#endif
-+}
-+
-+/**
-+* dal_bios_parser_prepare_scratch_active_and_requested
-+*
-+* @brief
-+* update VBIOS scratch registers about active and requested displays
-+*
-+* @param
-+* enum controller_id - controller Id
-+* enum signal_type signal - signal type used on display
-+* const struct connector_device_tag_info * - pointer to display type and
-+* enum Id
-+*/
-+void dal_bios_parser_prepare_scratch_active_and_requested(
-+ struct bios_parser *bp,
-+ enum controller_id controller_id,
-+ enum signal_type signal,
-+ const struct connector_device_tag_info *device_tag)
-+{
-+#ifdef CONFIG_DRM_AMD_DAL_VBIOS_PRESENT
-+ bp->bios_helper->prepare_scratch_active_and_requested(
-+ bp->ctx,
-+ &bp->vbios_helper_data,
-+ controller_id,
-+ signal,
-+ device_tag);
-+#else
-+ dal_logger_write(bp->ctx->logger,
-+ LOG_MAJOR_BIOS,
-+ LOG_MINOR_BIOS_CMD_TABLE,
-+ "%s: VBIOS is not supported", __func__);
-+#endif
-+}
-+
-+void dal_bios_parser_set_scratch_active_and_requested(
-+ struct bios_parser *bp)
-+{
-+#ifdef CONFIG_DRM_AMD_DAL_VBIOS_PRESENT
-+ bp->bios_helper->set_scratch_active_and_requested(
-+ bp->ctx,
-+ &bp->vbios_helper_data);
-+#else
-+ dal_logger_write(bp->ctx->logger,
-+ LOG_MAJOR_BIOS,
-+ LOG_MINOR_BIOS_CMD_TABLE,
-+ "%s: VBIOS is not supported", __func__);
-+#endif
-+}
-+
-+/*
-+ * get_integrated_info_v8
-+ *
-+ * @brief
-+ * Get V8 integrated BIOS information
-+ *
-+ * @param
-+ * bios_parser *bp - [in]BIOS parser handler to get master data table
-+ * integrated_info *info - [out] store and output integrated info
-+ *
-+ * @return
-+ * enum bp_result - BP_RESULT_OK if information is available,
-+ * BP_RESULT_BADBIOSTABLE otherwise.
-+ */
-+static enum bp_result get_integrated_info_v8(
-+ struct bios_parser *bp,
-+ struct integrated_info *info)
-+{
-+ enum bp_result result = BP_RESULT_BADBIOSTABLE;
-+ ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *info_v8;
-+ uint32_t i;
-+
-+ info_v8 = GET_IMAGE(ATOM_INTEGRATED_SYSTEM_INFO_V1_8,
-+ bp->master_data_tbl->ListOfDataTables.IntegratedSystemInfo);
-+
-+ if (info_v8 != NULL) {
-+ info->boot_up_engine_clock =
-+ le32_to_cpu(info_v8->ulBootUpEngineClock) * 10;
-+ info->dentist_vco_freq =
-+ le32_to_cpu(info_v8->ulDentistVCOFreq) * 10;
-+ info->boot_up_uma_clock =
-+ le32_to_cpu(info_v8->ulBootUpUMAClock) * 10;
-+
-+ for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
-+ /* Convert [10KHz] into [KHz] */
-+ info->disp_clk_voltage[i].max_supported_clk =
-+ le32_to_cpu(info_v8->sDISPCLK_Voltage[i].
-+ ulMaximumSupportedCLK) * 10;
-+ info->disp_clk_voltage[i].voltage_index =
-+ le32_to_cpu(info_v8->sDISPCLK_Voltage[i].ulVoltageIndex);
-+ }
-+
-+ info->boot_up_req_display_vector =
-+ le32_to_cpu(info_v8->ulBootUpReqDisplayVector);
-+ info->gpu_cap_info =
-+ le32_to_cpu(info_v8->ulGPUCapInfo);
-+
-+ /*
-+ * system_config: Bit[0] = 0 : PCIE power gating disabled
-+ * = 1 : PCIE power gating enabled
-+ * Bit[1] = 0 : DDR-PLL shut down disabled
-+ * = 1 : DDR-PLL shut down enabled
-+ * Bit[2] = 0 : DDR-PLL power down disabled
-+ * = 1 : DDR-PLL power down enabled
-+ */
-+ info->system_config = le32_to_cpu(info_v8->ulSystemConfig);
-+ info->cpu_cap_info = le32_to_cpu(info_v8->ulCPUCapInfo);
-+ info->boot_up_nb_voltage =
-+ le16_to_cpu(info_v8->usBootUpNBVoltage);
-+ info->ext_disp_conn_info_offset =
-+ le16_to_cpu(info_v8->usExtDispConnInfoOffset);
-+ info->memory_type = info_v8->ucMemoryType;
-+ info->ma_channel_number = info_v8->ucUMAChannelNumber;
-+ info->gmc_restore_reset_time =
-+ le32_to_cpu(info_v8->ulGMCRestoreResetTime);
-+
-+ info->minimum_n_clk =
-+ le32_to_cpu(info_v8->ulNbpStateNClkFreq[0]);
-+ for (i = 1; i < 4; ++i)
-+ info->minimum_n_clk =
-+ info->minimum_n_clk < le32_to_cpu(info_v8->ulNbpStateNClkFreq[i]) ?
-+ info->minimum_n_clk : le32_to_cpu(info_v8->ulNbpStateNClkFreq[i]);
-+
-+ info->idle_n_clk = le32_to_cpu(info_v8->ulIdleNClk);
-+ info->ddr_dll_power_up_time =
-+ le32_to_cpu(info_v8->ulDDR_DLL_PowerUpTime);
-+ info->ddr_pll_power_up_time =
-+ le32_to_cpu(info_v8->ulDDR_PLL_PowerUpTime);
-+ info->pcie_clk_ss_type = le16_to_cpu(info_v8->usPCIEClkSSType);
-+ info->lvds_ss_percentage =
-+ le16_to_cpu(info_v8->usLvdsSSPercentage);
-+ info->lvds_sspread_rate_in_10hz =
-+ le16_to_cpu(info_v8->usLvdsSSpreadRateIn10Hz);
-+ info->hdmi_ss_percentage =
-+ le16_to_cpu(info_v8->usHDMISSPercentage);
-+ info->hdmi_sspread_rate_in_10hz =
-+ le16_to_cpu(info_v8->usHDMISSpreadRateIn10Hz);
-+ info->dvi_ss_percentage =
-+ le16_to_cpu(info_v8->usDVISSPercentage);
-+ info->dvi_sspread_rate_in_10_hz =
-+ le16_to_cpu(info_v8->usDVISSpreadRateIn10Hz);
-+
-+ info->max_lvds_pclk_freq_in_single_link =
-+ le16_to_cpu(info_v8->usMaxLVDSPclkFreqInSingleLink);
-+ info->lvds_misc = info_v8->ucLvdsMisc;
-+ info->lvds_pwr_on_seq_dig_on_to_de_in_4ms =
-+ info_v8->ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
-+ info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms =
-+ info_v8->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
-+ info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms =
-+ info_v8->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
-+ info->lvds_pwr_off_seq_vary_bl_to_de_in4ms =
-+ info_v8->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
-+ info->lvds_pwr_off_seq_de_to_dig_on_in4ms =
-+ info_v8->ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
-+ info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms =
-+ info_v8->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
-+ info->lvds_off_to_on_delay_in_4ms =
-+ info_v8->ucLVDSOffToOnDelay_in4Ms;
-+ info->lvds_bit_depth_control_val =
-+ le32_to_cpu(info_v8->ulLCDBitDepthControlVal);
-+
-+ for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) {
-+ /* Convert [10KHz] into [KHz] */
-+ info->avail_s_clk[i].supported_s_clk =
-+ le32_to_cpu(info_v8->sAvail_SCLK[i].ulSupportedSCLK) * 10;
-+ info->avail_s_clk[i].voltage_index =
-+ le16_to_cpu(info_v8->sAvail_SCLK[i].usVoltageIndex);
-+ info->avail_s_clk[i].voltage_id =
-+ le16_to_cpu(info_v8->sAvail_SCLK[i].usVoltageID);
-+ }
-+
-+ for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
-+ info->ext_disp_conn_info.gu_id[i] =
-+ info_v8->sExtDispConnInfo.ucGuid[i];
-+ }
-+
-+ for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
-+ info->ext_disp_conn_info.path[i].device_connector_id =
-+ object_id_from_bios_object_id(
-+ le16_to_cpu(info_v8->sExtDispConnInfo.sPath[i].usDeviceConnector));
-+
-+ info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
-+ object_id_from_bios_object_id(
-+ le16_to_cpu(info_v8->sExtDispConnInfo.sPath[i].usExtEncoderObjId));
-+
-+ info->ext_disp_conn_info.path[i].device_tag =
-+ le16_to_cpu(info_v8->sExtDispConnInfo.sPath[i].usDeviceTag);
-+ info->ext_disp_conn_info.path[i].device_acpi_enum =
-+ le16_to_cpu(info_v8->sExtDispConnInfo.sPath[i].usDeviceACPIEnum);
-+ info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
-+ info_v8->sExtDispConnInfo.sPath[i].ucExtAUXDDCLutIndex;
-+ info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
-+ info_v8->sExtDispConnInfo.sPath[i].ucExtHPDPINLutIndex;
-+ info->ext_disp_conn_info.path[i].channel_mapping.raw =
-+ info_v8->sExtDispConnInfo.sPath[i].ucChannelMapping;
-+ }
-+ info->ext_disp_conn_info.checksum =
-+ info_v8->sExtDispConnInfo.ucChecksum;
-+
-+ result = BP_RESULT_OK;
-+ }
-+
-+ return result;
-+}
-+
-+/*
-+ * get_integrated_info_v8
-+ *
-+ * @brief
-+ * Get V8 integrated BIOS information
-+ *
-+ * @param
-+ * bios_parser *bp - [in]BIOS parser handler to get master data table
-+ * integrated_info *info - [out] store and output integrated info
-+ *
-+ * @return
-+ * enum bp_result - BP_RESULT_OK if information is available,
-+ * BP_RESULT_BADBIOSTABLE otherwise.
-+ */
-+static enum bp_result get_integrated_info_v9(
-+ struct bios_parser *bp,
-+ struct integrated_info *info)
-+{
-+ enum bp_result result = BP_RESULT_BADBIOSTABLE;
-+ ATOM_INTEGRATED_SYSTEM_INFO_V1_9 *info_v9;
-+ uint32_t i;
-+
-+ info_v9 = GET_IMAGE(ATOM_INTEGRATED_SYSTEM_INFO_V1_9,
-+ bp->master_data_tbl->ListOfDataTables.IntegratedSystemInfo);
-+
-+ if (info_v9 != NULL) {
-+ info->boot_up_engine_clock =
-+ le32_to_cpu(info_v9->ulBootUpEngineClock) * 10;
-+ info->dentist_vco_freq =
-+ le32_to_cpu(info_v9->ulDentistVCOFreq) * 10;
-+ info->boot_up_uma_clock =
-+ le32_to_cpu(info_v9->ulBootUpUMAClock) * 10;
-+
-+ for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
-+ /* Convert [10KHz] into [KHz] */
-+ info->disp_clk_voltage[i].max_supported_clk =
-+ le32_to_cpu(info_v9->sDISPCLK_Voltage[i].ulMaximumSupportedCLK) * 10;
-+ info->disp_clk_voltage[i].voltage_index =
-+ le32_to_cpu(info_v9->sDISPCLK_Voltage[i].ulVoltageIndex);
-+ }
-+
-+ info->boot_up_req_display_vector =
-+ le32_to_cpu(info_v9->ulBootUpReqDisplayVector);
-+ info->gpu_cap_info = le32_to_cpu(info_v9->ulGPUCapInfo);
-+
-+ /*
-+ * system_config: Bit[0] = 0 : PCIE power gating disabled
-+ * = 1 : PCIE power gating enabled
-+ * Bit[1] = 0 : DDR-PLL shut down disabled
-+ * = 1 : DDR-PLL shut down enabled
-+ * Bit[2] = 0 : DDR-PLL power down disabled
-+ * = 1 : DDR-PLL power down enabled
-+ */
-+ info->system_config = le32_to_cpu(info_v9->ulSystemConfig);
-+ info->cpu_cap_info = le32_to_cpu(info_v9->ulCPUCapInfo);
-+ info->boot_up_nb_voltage =
-+ le16_to_cpu(info_v9->usBootUpNBVoltage);
-+ info->ext_disp_conn_info_offset =
-+ le16_to_cpu(info_v9->usExtDispConnInfoOffset);
-+ info->memory_type = info_v9->ucMemoryType;
-+ info->ma_channel_number = info_v9->ucUMAChannelNumber;
-+ info->gmc_restore_reset_time =
-+ le32_to_cpu(info_v9->ulGMCRestoreResetTime);
-+
-+ info->minimum_n_clk =
-+ le32_to_cpu(info_v9->ulNbpStateNClkFreq[0]);
-+ for (i = 1; i < 4; ++i)
-+ info->minimum_n_clk =
-+ info->minimum_n_clk < le32_to_cpu(info_v9->ulNbpStateNClkFreq[i]) ?
-+ info->minimum_n_clk : le32_to_cpu(info_v9->ulNbpStateNClkFreq[i]);
-+
-+ info->idle_n_clk = le32_to_cpu(info_v9->ulIdleNClk);
-+ info->ddr_dll_power_up_time =
-+ le32_to_cpu(info_v9->ulDDR_DLL_PowerUpTime);
-+ info->ddr_pll_power_up_time =
-+ le32_to_cpu(info_v9->ulDDR_PLL_PowerUpTime);
-+ info->pcie_clk_ss_type = le16_to_cpu(info_v9->usPCIEClkSSType);
-+ info->lvds_ss_percentage =
-+ le16_to_cpu(info_v9->usLvdsSSPercentage);
-+ info->lvds_sspread_rate_in_10hz =
-+ le16_to_cpu(info_v9->usLvdsSSpreadRateIn10Hz);
-+ info->hdmi_ss_percentage =
-+ le16_to_cpu(info_v9->usHDMISSPercentage);
-+ info->hdmi_sspread_rate_in_10hz =
-+ le16_to_cpu(info_v9->usHDMISSpreadRateIn10Hz);
-+ info->dvi_ss_percentage =
-+ le16_to_cpu(info_v9->usDVISSPercentage);
-+ info->dvi_sspread_rate_in_10_hz =
-+ le16_to_cpu(info_v9->usDVISSpreadRateIn10Hz);
-+
-+ info->max_lvds_pclk_freq_in_single_link =
-+ le16_to_cpu(info_v9->usMaxLVDSPclkFreqInSingleLink);
-+ info->lvds_misc = info_v9->ucLvdsMisc;
-+ info->lvds_pwr_on_seq_dig_on_to_de_in_4ms =
-+ info_v9->ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
-+ info->lvds_pwr_on_seq_de_to_vary_bl_in_4ms =
-+ info_v9->ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
-+ info->lvds_pwr_on_seq_vary_bl_to_blon_in_4ms =
-+ info_v9->ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
-+ info->lvds_pwr_off_seq_vary_bl_to_de_in4ms =
-+ info_v9->ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
-+ info->lvds_pwr_off_seq_de_to_dig_on_in4ms =
-+ info_v9->ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
-+ info->lvds_pwr_off_seq_blon_to_vary_bl_in_4ms =
-+ info_v9->ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
-+ info->lvds_off_to_on_delay_in_4ms =
-+ info_v9->ucLVDSOffToOnDelay_in4Ms;
-+ info->lvds_bit_depth_control_val =
-+ le32_to_cpu(info_v9->ulLCDBitDepthControlVal);
-+
-+ for (i = 0; i < NUMBER_OF_AVAILABLE_SCLK; ++i) {
-+ /* Convert [10KHz] into [KHz] */
-+ info->avail_s_clk[i].supported_s_clk =
-+ le32_to_cpu(info_v9->sAvail_SCLK[i].ulSupportedSCLK) * 10;
-+ info->avail_s_clk[i].voltage_index =
-+ le16_to_cpu(info_v9->sAvail_SCLK[i].usVoltageIndex);
-+ info->avail_s_clk[i].voltage_id =
-+ le16_to_cpu(info_v9->sAvail_SCLK[i].usVoltageID);
-+ }
-+
-+ for (i = 0; i < NUMBER_OF_UCHAR_FOR_GUID; ++i) {
-+ info->ext_disp_conn_info.gu_id[i] =
-+ info_v9->sExtDispConnInfo.ucGuid[i];
-+ }
-+
-+ for (i = 0; i < MAX_NUMBER_OF_EXT_DISPLAY_PATH; ++i) {
-+ info->ext_disp_conn_info.path[i].device_connector_id =
-+ object_id_from_bios_object_id(
-+ le16_to_cpu(info_v9->sExtDispConnInfo.sPath[i].usDeviceConnector));
-+
-+ info->ext_disp_conn_info.path[i].ext_encoder_obj_id =
-+ object_id_from_bios_object_id(
-+ le16_to_cpu(info_v9->sExtDispConnInfo.sPath[i].usExtEncoderObjId));
-+
-+ info->ext_disp_conn_info.path[i].device_tag =
-+ le16_to_cpu(info_v9->sExtDispConnInfo.sPath[i].usDeviceTag);
-+ info->ext_disp_conn_info.path[i].device_acpi_enum =
-+ le16_to_cpu(info_v9->sExtDispConnInfo.sPath[i].usDeviceACPIEnum);
-+ info->ext_disp_conn_info.path[i].ext_aux_ddc_lut_index =
-+ info_v9->sExtDispConnInfo.sPath[i].ucExtAUXDDCLutIndex;
-+ info->ext_disp_conn_info.path[i].ext_hpd_pin_lut_index =
-+ info_v9->sExtDispConnInfo.sPath[i].ucExtHPDPINLutIndex;
-+ info->ext_disp_conn_info.path[i].channel_mapping.raw =
-+ info_v9->sExtDispConnInfo.sPath[i].ucChannelMapping;
-+ }
-+ info->ext_disp_conn_info.checksum =
-+ info_v9->sExtDispConnInfo.ucChecksum;
-+
-+ result = BP_RESULT_OK;
-+ }
-+
-+ return result;
-+}
-+
-+/*
-+ * construct_integrated_info
-+ *
-+ * @brief
-+ * Get integrated BIOS information based on table revision
-+ *
-+ * @param
-+ * bios_parser *bp - [in]BIOS parser handler to get master data table
-+ * integrated_info *info - [out] store and output integrated info
-+ *
-+ * @return
-+ * enum bp_result - BP_RESULT_OK if information is available,
-+ * BP_RESULT_BADBIOSTABLE otherwise.
-+ */
-+static enum bp_result construct_integrated_info(
-+ struct bios_parser *bp,
-+ struct integrated_info *info)
-+{
-+ enum bp_result result = BP_RESULT_BADBIOSTABLE;
-+
-+ ATOM_COMMON_TABLE_HEADER *header;
-+ struct atom_data_revision revision;
-+
-+ if (info != NULL &&
-+ bp->master_data_tbl->ListOfDataTables.IntegratedSystemInfo) {
-+ header = GET_IMAGE(ATOM_COMMON_TABLE_HEADER,
-+ bp->master_data_tbl->ListOfDataTables.IntegratedSystemInfo);
-+
-+ get_atom_data_table_revision(header, &revision);
-+
-+ /* Don't need to check major revision as they are all 1 */
-+ switch (revision.minor) {
-+ case 8:
-+ result = get_integrated_info_v8(bp, info);
-+ break;
-+ case 9:
-+ result = get_integrated_info_v9(bp, info);
-+ break;
-+ default:
-+ return result;
-+
-+ }
-+ }
-+
-+ /* Sort voltage table from low to high*/
-+ if (result == BP_RESULT_OK) {
-+ struct clock_voltage_caps temp = {0, 0};
-+ uint32_t i;
-+ uint32_t j;
-+
-+ for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
-+ for (j = i; j > 0; --j) {
-+ if (
-+ info->disp_clk_voltage[j].max_supported_clk <
-+ info->disp_clk_voltage[j-1].max_supported_clk) {
-+ /* swap j and j - 1*/
-+ temp = info->disp_clk_voltage[j-1];
-+ info->disp_clk_voltage[j-1] =
-+ info->disp_clk_voltage[j];
-+ info->disp_clk_voltage[j] = temp;
-+ }
-+ }
-+ }
-+
-+ }
-+
-+ return result;
-+}
-+
-+/*
-+ * dal_bios_parser_create_integrated_info
-+ *
-+ * @brief
-+ * Create integrated info
-+ *
-+ * @param
-+ * bios_parser *bp - [in] BIOS parser handler
-+ *
-+ * @return
-+ * struct integrated_info * - pointer to the newly created integrated info
-+ */
-+struct integrated_info *dal_bios_parser_create_integrated_info(
-+ struct bios_parser *bp)
-+{
-+ struct integrated_info *info = NULL;
-+
-+ info = dc_service_alloc(bp->ctx, sizeof(struct integrated_info));
-+
-+ if (info == NULL) {
-+ ASSERT_CRITICAL(0);
-+ return NULL;
-+ }
-+
-+ if (construct_integrated_info(bp, info) == BP_RESULT_OK)
-+ return info;
-+
-+ dc_service_free(bp->ctx, info);
-+
-+ return NULL;
-+}
-+
-+/*
-+ * dal_bios_parser_destroy_integrated_info
-+ *
-+ * @brief
-+ * Destroy provided integrated info
-+ *
-+ * @param
-+ * struct integrated_info **info - [in] info to be destroied
-+ */
-+void dal_bios_parser_destroy_integrated_info(struct dc_context *ctx, struct integrated_info **info)
-+{
-+ if (info == NULL) {
-+ ASSERT_CRITICAL(0);
-+ return;
-+ }
-+
-+ if (*info != NULL) {
-+ dc_service_free(ctx, *info);
-+ *info = NULL;
-+ }
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/bios_parser.h b/drivers/gpu/drm/amd/dal/dc/bios/bios_parser.h
-new file mode 100644
-index 0000000..db169f1
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/bios_parser.h
-@@ -0,0 +1,78 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_BIOS_PARSER_H__
-+#define __DAL_BIOS_PARSER_H__
-+
-+#include "bios_parser_helper.h"
-+
-+struct atom_data_revision {
-+ uint32_t major;
-+ uint32_t minor;
-+};
-+
-+struct object_info_table {
-+ struct atom_data_revision revision;
-+ union {
-+ ATOM_OBJECT_HEADER *v1_1;
-+ ATOM_OBJECT_HEADER_V3 *v1_3;
-+ };
-+};
-+
-+enum spread_spectrum_id {
-+ SS_ID_UNKNOWN = 0,
-+ SS_ID_DP1 = 0xf1,
-+ SS_ID_DP2 = 0xf2,
-+ SS_ID_LVLINK_2700MHZ = 0xf3,
-+ SS_ID_LVLINK_1620MHZ = 0xf4
-+};
-+
-+struct bios_parser {
-+ struct dc_context *ctx;
-+ struct adapter_service *as;
-+
-+ struct object_info_table object_info_tbl;
-+ uint32_t object_info_tbl_offset;
-+ ATOM_MASTER_DATA_TABLE *master_data_tbl;
-+
-+ uint8_t *bios;
-+ uint32_t bios_size;
-+
-+#if defined(CONFIG_DRM_AMD_DAL_VBIOS_PRESENT)
-+ const struct bios_parser_helper *bios_helper;
-+ struct vbios_helper_data vbios_helper_data;
-+#endif /* CONFIG_DRM_AMD_DAL_VBIOS_PRESENT */
-+
-+ const struct command_table_helper *cmd_helper;
-+ struct cmd_tbl cmd_tbl;
-+
-+ uint8_t *bios_local_image;
-+ enum lcd_scale lcd_scale;
-+
-+ bool remap_device_tags;
-+ bool headless_no_opm;
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.c b/drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.c
-new file mode 100644
-index 0000000..0089800
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.c
-@@ -0,0 +1,193 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "atom.h"
-+
-+#include "include/bios_parser_types.h"
-+#include "include/adapter_service_types.h"
-+#include "bios_parser_helper.h"
-+#include "command_table_helper.h"
-+#include "command_table.h"
-+#include "bios_parser.h"
-+
-+bool dal_bios_parser_init_bios_helper(
-+ struct bios_parser *bp,
-+ enum dce_version version)
-+{
-+ switch (version) {
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ case DCE_VERSION_11_0:
-+ bp->bios_helper = dal_bios_parser_helper_dce110_get_table();
-+ return true;
-+
-+#endif
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+}
-+
-+bool dal_bios_parser_is_lid_open(
-+ struct bios_parser *bp)
-+{
-+ const struct graphics_object_id encoder = dal_graphics_object_id_init(
-+ ENCODER_ID_INTERNAL_UNIPHY,
-+ ENUM_ID_UNKNOWN,
-+ OBJECT_TYPE_UNKNOWN);
-+ const struct graphics_object_id connector = dal_graphics_object_id_init(
-+ CONNECTOR_ID_LVDS,
-+ ENUM_ID_UNKNOWN,
-+ OBJECT_TYPE_UNKNOWN);
-+
-+ enum signal_type signal;
-+
-+ /* check if VBIOS reported LCD as connected */
-+ signal = bp->bios_helper->detect_sink(bp->ctx,
-+ encoder, connector, SIGNAL_TYPE_LVDS);
-+
-+ if (signal == SIGNAL_TYPE_NONE)
-+ return false;
-+
-+ return bp->bios_helper->is_lid_open(bp->ctx);
-+}
-+
-+bool dal_bios_parser_is_lid_status_changed(
-+ struct bios_parser *bp)
-+{
-+ return bp->bios_helper->is_lid_status_changed(
-+ bp->ctx);
-+}
-+
-+bool dal_bios_parser_is_display_config_changed(
-+ struct bios_parser *bp)
-+{
-+ return bp->bios_helper->is_display_config_changed(
-+ bp->ctx);
-+}
-+
-+/**
-+* dal_bios_parser_set_scratch_lcd_scale
-+*
-+* @brief
-+* update VBIOS scratch pad registers about LCD scale
-+*
-+* @param
-+* bool - to set to full panel mode or aspect-ratio mode
-+*/
-+void dal_bios_parser_set_scratch_lcd_scale(
-+ struct bios_parser *bp,
-+ enum lcd_scale scale)
-+{
-+ bp->bios_helper->set_scratch_lcd_scale(
-+ bp->ctx, scale);
-+}
-+
-+/**
-+* dal_bios_parser_get_scratch_lcd_scale
-+*
-+* @brief
-+* get LCD Scale Mode from VBIOS scratch register
-+*
-+* @param
-+* NONE
-+*/
-+enum lcd_scale dal_bios_parser_get_scratch_lcd_scale(
-+ struct bios_parser *bp)
-+{
-+ return bp->bios_helper->get_scratch_lcd_scale(
-+ bp->ctx);
-+}
-+
-+void dal_bios_parser_get_bios_event_info(
-+ struct bios_parser *bp,
-+ struct bios_event_info *info)
-+{
-+ bp->bios_helper->get_bios_event_info(
-+ bp->ctx, info);
-+}
-+
-+/* ABM related */
-+
-+void dal_bios_parser_update_requested_backlight_level(
-+ struct bios_parser *bp,
-+ uint32_t backlight_8bit)
-+{
-+ bp->bios_helper->update_requested_backlight_level(
-+ bp->ctx,
-+ backlight_8bit);
-+}
-+
-+uint32_t dal_bios_parser_get_requested_backlight_level(
-+ struct bios_parser *bp)
-+{
-+ return bp->bios_helper->get_requested_backlight_level(
-+ bp->ctx);
-+}
-+
-+void dal_bios_parser_take_backlight_control(
-+ struct bios_parser *bp,
-+ bool cntl)
-+{
-+ bp->bios_helper->take_backlight_control(
-+ bp->ctx, cntl);
-+}
-+
-+/**
-+ * dal_bios_parser_is_active_display
-+ * Check video bios active display.
-+ */
-+bool dal_bios_parser_is_active_display(
-+ struct bios_parser *bp,
-+ enum signal_type signal,
-+ const struct connector_device_tag_info *device_tag)
-+{
-+ return bp->bios_helper->is_active_display(
-+ bp->ctx, signal, device_tag);
-+}
-+
-+/**
-+ * dal_bios_parser_get_embedded_display_controller_id
-+ * Get controller ID for embedded display from scratch registers
-+ */
-+enum controller_id dal_bios_parser_get_embedded_display_controller_id(
-+ struct bios_parser *bp)
-+{
-+ return bp->bios_helper->get_embedded_display_controller_id(
-+ bp->ctx);
-+}
-+
-+/**
-+ * dal_bios_parser_get_embedded_display_refresh_rate
-+ * Get refresh rate for embedded display from scratch registers
-+ */
-+uint32_t dal_bios_parser_get_embedded_display_refresh_rate(
-+ struct bios_parser *bp)
-+{
-+ return bp->bios_helper->get_embedded_display_refresh_rate(
-+ bp->ctx);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.h b/drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.h
-new file mode 100644
-index 0000000..d0e9de9
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.h
-@@ -0,0 +1,108 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_BIOS_PARSER_HELPER_H__
-+#define __DAL_BIOS_PARSER_HELPER_H__
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+#include "dce110/bios_parser_helper_dce110.h"
-+#endif
-+
-+struct bios_parser;
-+
-+struct vbios_helper_data {
-+ uint32_t active;
-+ uint32_t requested;
-+};
-+
-+struct bios_parser_helper {
-+ enum signal_type (*detect_sink)(
-+ struct dc_context *ctx,
-+ struct graphics_object_id encoder,
-+ struct graphics_object_id connector,
-+ enum signal_type signal);
-+ bool (*is_lid_open)(
-+ struct dc_context *ctx);
-+ bool (*is_lid_status_changed)(
-+ struct dc_context *ctx);
-+ bool (*is_display_config_changed)(
-+ struct dc_context *ctx);
-+ void (*set_scratch_acc_mode_change)(
-+ struct dc_context *ctx);
-+ bool (*is_accelerated_mode)(
-+ struct dc_context *ctx);
-+ void (*set_scratch_critical_state)(
-+ struct dc_context *ctx,
-+ bool state);
-+ void (*prepare_scratch_active_and_requested)(
-+ struct dc_context *ctx,
-+ struct vbios_helper_data *data,
-+ enum controller_id id, enum signal_type s,
-+ const struct connector_device_tag_info *dev_tag);
-+ void (*set_scratch_active_and_requested)(
-+ struct dc_context *ctx,
-+ struct vbios_helper_data *d);
-+ void (*set_scratch_connected)(
-+ struct dc_context *ctx,
-+ struct graphics_object_id id,
-+ bool connected,
-+ const struct connector_device_tag_info *device_tag);
-+ void (*set_scratch_lcd_scale)(
-+ struct dc_context *ctx,
-+ enum lcd_scale lcd_scale_request);
-+ enum lcd_scale (*get_scratch_lcd_scale)(
-+ struct dc_context *ctx);
-+ uint32_t (*fmt_control)(
-+ struct dc_context *ctx,
-+ enum controller_id id, uint32_t *value);
-+ uint32_t (*fmt_bit_depth_control)(
-+ struct dc_context *ctx,
-+ enum controller_id id,
-+ uint32_t *value);
-+ void (*get_bios_event_info)(
-+ struct dc_context *ctx,
-+ struct bios_event_info *info);
-+ void (*take_backlight_control)(
-+ struct dc_context *ctx, bool control);
-+ uint32_t (*get_requested_backlight_level)(
-+ struct dc_context *ctx);
-+ void (*update_requested_backlight_level)(
-+ struct dc_context *ctx,
-+ uint32_t backlight_8bit);
-+ bool (*is_active_display)(
-+ struct dc_context *ctx,
-+ enum signal_type signal,
-+ const struct connector_device_tag_info *dev_tag);
-+ enum controller_id (*get_embedded_display_controller_id)(
-+ struct dc_context *ctx);
-+ uint32_t (*get_embedded_display_refresh_rate)(
-+ struct dc_context *ctx);
-+};
-+
-+bool dal_bios_parser_init_bios_helper(
-+ struct bios_parser *bp,
-+ enum dce_version ver);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/command_table.c b/drivers/gpu/drm/amd/dal/dc/bios/command_table.c
-new file mode 100644
-index 0000000..a807ab6
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/command_table.c
-@@ -0,0 +1,2616 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "atom.h"
-+
-+#include "include/bios_parser_interface.h"
-+
-+#include "command_table.h"
-+#include "command_table_helper.h"
-+#include "bios_parser_helper.h"
-+#include "bios_parser.h"
-+
-+#define EXEC_BIOS_CMD_TABLE(command, params)\
-+ (cgs_atom_exec_cmd_table(bp->ctx->cgs_device, \
-+ GetIndexIntoMasterTable(COMMAND, command), \
-+ &params) == 0)
-+
-+#define BIOS_CMD_TABLE_REVISION(command, frev, crev)\
-+ cgs_atom_get_cmd_table_revs(bp->ctx->cgs_device, \
-+ GetIndexIntoMasterTable(COMMAND, command), &frev, &crev)
-+
-+#define BIOS_CMD_TABLE_PARA_REVISION(command)\
-+ dal_bios_cmd_table_para_revision(bp->ctx, \
-+ GetIndexIntoMasterTable(COMMAND, command))
-+
-+
-+static void init_dig_encoder_control(struct bios_parser *bp);
-+static void init_dvo_encoder_control(struct bios_parser *bp);
-+static void init_transmitter_control(struct bios_parser *bp);
-+static void init_set_pixel_clock(struct bios_parser *bp);
-+static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp);
-+static void init_adjust_display_pll(struct bios_parser *bp);
-+static void init_dac_encoder_control(struct bios_parser *bp);
-+static void init_dac_output_control(struct bios_parser *bp);
-+static void init_dac_load_detection(struct bios_parser *bp);
-+static void init_blank_crtc(struct bios_parser *bp);
-+static void init_set_crtc_timing(struct bios_parser *bp);
-+static void init_set_crtc_overscan(struct bios_parser *bp);
-+static void init_select_crtc_source(struct bios_parser *bp);
-+static void init_enable_crtc(struct bios_parser *bp);
-+static void init_enable_crtc_mem_req(struct bios_parser *bp);
-+static void init_compute_memore_engine_pll(struct bios_parser *bp);
-+static void init_external_encoder_control(struct bios_parser *bp);
-+static void init_enable_disp_power_gating(struct bios_parser *bp);
-+static void init_program_clock(struct bios_parser *bp);
-+
-+void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp)
-+{
-+ init_dig_encoder_control(bp);
-+ init_dvo_encoder_control(bp);
-+ init_transmitter_control(bp);
-+ init_set_pixel_clock(bp);
-+ init_enable_spread_spectrum_on_ppll(bp);
-+ init_adjust_display_pll(bp);
-+ init_dac_encoder_control(bp);
-+ init_dac_output_control(bp);
-+ init_dac_load_detection(bp);
-+ init_blank_crtc(bp);
-+ init_set_crtc_timing(bp);
-+ init_set_crtc_overscan(bp);
-+ init_select_crtc_source(bp);
-+ init_enable_crtc(bp);
-+ init_enable_crtc_mem_req(bp);
-+ init_program_clock(bp);
-+ init_compute_memore_engine_pll(bp);
-+ init_external_encoder_control(bp);
-+ init_enable_disp_power_gating(bp);
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** D I G E N C O D E R C O N T R O L
-+**
-+********************************************************************************
-+*******************************************************************************/
-+static enum bp_result encoder_control_digx_v3(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl);
-+
-+static enum bp_result encoder_control_digx_v4(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl);
-+static void init_encoder_control_dig_v1(struct bios_parser *bp);
-+
-+static void init_dig_encoder_control(struct bios_parser *bp)
-+{
-+ uint32_t version =
-+ BIOS_CMD_TABLE_PARA_REVISION(DIGxEncoderControl);
-+
-+ switch (version) {
-+ case 4:
-+ bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v4;
-+ break;
-+ case 2:
-+ bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v3;
-+ break;
-+ default:
-+ init_encoder_control_dig_v1(bp);
-+ break;
-+ }
-+}
-+
-+static enum bp_result encoder_control_dig_v1(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl);
-+static enum bp_result encoder_control_dig1_v1(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl);
-+static enum bp_result encoder_control_dig2_v1(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl);
-+
-+static void init_encoder_control_dig_v1(struct bios_parser *bp)
-+{
-+ struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
-+
-+ if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG1EncoderControl))
-+ cmd_tbl->encoder_control_dig1 = encoder_control_dig1_v1;
-+ else
-+ cmd_tbl->encoder_control_dig1 = NULL;
-+
-+ if (1 == BIOS_CMD_TABLE_PARA_REVISION(DIG2EncoderControl))
-+ cmd_tbl->encoder_control_dig2 = encoder_control_dig2_v1;
-+ else
-+ cmd_tbl->encoder_control_dig2 = NULL;
-+
-+ cmd_tbl->dig_encoder_control = encoder_control_dig_v1;
-+}
-+
-+static enum bp_result encoder_control_dig_v1(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ struct cmd_tbl *cmd_tbl = &bp->cmd_tbl;
-+
-+ if (cntl != NULL)
-+ switch (cntl->engine_id) {
-+ case ENGINE_ID_DIGA:
-+ if (cmd_tbl->encoder_control_dig1 != NULL)
-+ result =
-+ cmd_tbl->encoder_control_dig1(bp, cntl);
-+ break;
-+ case ENGINE_ID_DIGB:
-+ if (cmd_tbl->encoder_control_dig2 != NULL)
-+ result =
-+ cmd_tbl->encoder_control_dig2(bp, cntl);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ return result;
-+}
-+
-+static enum bp_result encoder_control_dig1_v1(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
-+
-+ bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, &params);
-+
-+ if (EXEC_BIOS_CMD_TABLE(DIG1EncoderControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+static enum bp_result encoder_control_dig2_v1(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ DIG_ENCODER_CONTROL_PARAMETERS_V2 params = {0};
-+
-+ bp->cmd_helper->assign_control_parameter(bp->cmd_helper, cntl, &params);
-+
-+ if (EXEC_BIOS_CMD_TABLE(DIG2EncoderControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+static enum bp_result encoder_control_digx_v3(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ DIG_ENCODER_CONTROL_PARAMETERS_V3 params = {0};
-+
-+ if (LANE_COUNT_FOUR < cntl->lanes_number)
-+ params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */
-+ else
-+ params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
-+
-+ params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
-+
-+ /* We need to convert from KHz units into 10KHz units */
-+ params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
-+ params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
-+ params.ucEncoderMode =
-+ (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
-+ cntl->signal,
-+ cntl->enable_dp_audio);
-+ params.ucLaneNum = (uint8_t)(cntl->lanes_number);
-+
-+ if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-+ switch (cntl->color_depth) {
-+ case COLOR_DEPTH_101010:
-+ params.usPixelClock =
-+ cpu_to_le16((le32_to_cpu(params.usPixelClock) * 30) / 24);
-+ break;
-+ case COLOR_DEPTH_121212:
-+ params.usPixelClock =
-+ cpu_to_le16((le32_to_cpu(params.usPixelClock) * 36) / 24);
-+ break;
-+ case COLOR_DEPTH_161616:
-+ params.usPixelClock =
-+ cpu_to_le16((le32_to_cpu(params.usPixelClock) * 48) / 24);
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+static enum bp_result encoder_control_digx_v4(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ DIG_ENCODER_CONTROL_PARAMETERS_V4 params = {0};
-+
-+ if (LANE_COUNT_FOUR < cntl->lanes_number)
-+ params.acConfig.ucDPLinkRate = 1; /* dual link 2.7GHz */
-+ else
-+ params.acConfig.ucDPLinkRate = 0; /* single link 1.62GHz */
-+
-+
-+ params.acConfig.ucDigSel = (uint8_t)(cntl->engine_id);
-+
-+ /* We need to convert from KHz units into 10KHz units */
-+ params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
-+ params.usPixelClock = cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
-+ params.ucEncoderMode =
-+ (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
-+ cntl->signal,
-+ cntl->enable_dp_audio));
-+ params.ucLaneNum = (uint8_t)(cntl->lanes_number);
-+
-+ if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-+ switch (cntl->color_depth) {
-+ case COLOR_DEPTH_101010:
-+ params.usPixelClock =
-+ cpu_to_le16((le32_to_cpu(params.usPixelClock) * 30) / 24);
-+ break;
-+ case COLOR_DEPTH_121212:
-+ params.usPixelClock =
-+ cpu_to_le16((le32_to_cpu(params.usPixelClock) * 36) / 24);
-+ break;
-+ case COLOR_DEPTH_161616:
-+ params.usPixelClock =
-+ cpu_to_le16((le32_to_cpu(params.usPixelClock) * 48) / 24);
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** DVO ENCODER CONTROL
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result dvo_encoder_control_v3(
-+ struct bios_parser *bp,
-+ struct bp_dvo_encoder_control *cntl);
-+
-+static void init_dvo_encoder_control(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(DVOEncoderControl)) {
-+ case 3:
-+ bp->cmd_tbl.dvo_encoder_control = dvo_encoder_control_v3;
-+ break;
-+ default:
-+ bp->cmd_tbl.dvo_encoder_control = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result dvo_encoder_control_v3(
-+ struct bios_parser *bp,
-+ struct bp_dvo_encoder_control *cntl)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ DVO_ENCODER_CONTROL_PARAMETERS_V3 params;
-+ uint8_t config = 0;
-+
-+ if (cntl->memory_rate == DVO_ENCODER_MEMORY_RATE_SDR)
-+ config |= DVO_ENCODER_CONFIG_SDR_SPEED;
-+
-+ switch (cntl->interface_width) {
-+ case DVO_ENCODER_INTERFACE_WIDTH_FULL24BIT:
-+ config |= DVO_ENCODER_CONFIG_24BIT;
-+ break;
-+ case DVO_ENCODER_INTERFACE_WIDTH_HIGH12BIT:
-+ config |= DVO_ENCODER_CONFIG_UPPER12BIT;
-+ break;
-+ default:
-+ config |= DVO_ENCODER_CONFIG_LOW12BIT;
-+ break;
-+ }
-+
-+ /* We need to convert from KHz units into 10KHz units */
-+ dc_service_memset(&params, 0, sizeof(params));
-+ params.ucAction = (uint8_t) cntl->action;
-+ params.usPixelClock = cpu_to_le16((uint16_t) (cntl->pixel_clock / 10));
-+ params.ucDVOConfig = config;
-+
-+ if (EXEC_BIOS_CMD_TABLE(DVOEncoderControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** TRANSMITTER CONTROL
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result transmitter_control_v2(
-+ struct bios_parser *bp,
-+ struct bp_transmitter_control *cntl);
-+static enum bp_result transmitter_control_v3(
-+ struct bios_parser *bp,
-+ struct bp_transmitter_control *cntl);
-+static enum bp_result transmitter_control_v4(
-+ struct bios_parser *bp,
-+ struct bp_transmitter_control *cntl);
-+static enum bp_result transmitter_control_v1_5(
-+ struct bios_parser *bp,
-+ struct bp_transmitter_control *cntl);
-+
-+static void init_transmitter_control(struct bios_parser *bp)
-+{
-+ uint8_t frev;
-+ uint8_t crev;
-+
-+ if (BIOS_CMD_TABLE_REVISION(UNIPHYTransmitterControl,
-+ frev, crev) != 0)
-+ BREAK_TO_DEBUGGER();
-+ switch (crev) {
-+ case 2:
-+ bp->cmd_tbl.transmitter_control = transmitter_control_v2;
-+ break;
-+ case 3:
-+ bp->cmd_tbl.transmitter_control = transmitter_control_v3;
-+ break;
-+ case 4:
-+ bp->cmd_tbl.transmitter_control = transmitter_control_v4;
-+ break;
-+ case 5:
-+ bp->cmd_tbl.transmitter_control = transmitter_control_v1_5;
-+ break;
-+ default:
-+ bp->cmd_tbl.transmitter_control = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result transmitter_control_v2(
-+ struct bios_parser *bp,
-+ struct bp_transmitter_control *cntl)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 params;
-+ enum connector_id connector_id =
-+ dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+
-+ switch (cntl->transmitter) {
-+ case TRANSMITTER_UNIPHY_A:
-+ case TRANSMITTER_UNIPHY_B:
-+ case TRANSMITTER_UNIPHY_C:
-+ case TRANSMITTER_UNIPHY_D:
-+ case TRANSMITTER_UNIPHY_E:
-+ case TRANSMITTER_UNIPHY_F:
-+ case TRANSMITTER_TRAVIS_LCD:
-+ break;
-+ default:
-+ return BP_RESULT_BADINPUT;
-+ }
-+
-+ switch (cntl->action) {
-+ case TRANSMITTER_CONTROL_INIT:
-+ if ((CONNECTOR_ID_DUAL_LINK_DVII == connector_id) ||
-+ (CONNECTOR_ID_DUAL_LINK_DVID == connector_id))
-+ /* on INIT this bit should be set according to the
-+ * phisycal connector
-+ * Bit0: dual link connector flag
-+ * =0 connector is single link connector
-+ * =1 connector is dual link connector
-+ */
-+ params.acConfig.fDualLinkConnector = 1;
-+
-+ /* connector object id */
-+ params.usInitInfo =
-+ cpu_to_le16((uint8_t)cntl->connector_obj_id.id);
-+ break;
-+ case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
-+ /* votage swing and pre-emphsis */
-+ params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
-+ params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
-+ break;
-+ default:
-+ /* if dual-link */
-+ if (LANE_COUNT_FOUR < cntl->lanes_number) {
-+ /* on ENABLE/DISABLE this bit should be set according to
-+ * actual timing (number of lanes)
-+ * Bit0: dual link connector flag
-+ * =0 connector is single link connector
-+ * =1 connector is dual link connector
-+ */
-+ params.acConfig.fDualLinkConnector = 1;
-+
-+ /* link rate, half for dual link
-+ * We need to convert from KHz units into 20KHz units
-+ */
-+ params.usPixelClock =
-+ cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
-+ } else
-+ /* link rate, half for dual link
-+ * We need to convert from KHz units into 10KHz units
-+ */
-+ params.usPixelClock =
-+ cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
-+ break;
-+ }
-+
-+ /* 00 - coherent mode
-+ * 01 - incoherent mode
-+ */
-+
-+ params.acConfig.fCoherentMode = cntl->coherent;
-+
-+ if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
-+ || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
-+ || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
-+ /* Bit2: Transmitter Link selection
-+ * =0 when bit0=0, single link A/C/E, when bit0=1,
-+ * master link A/C/E
-+ * =1 when bit0=0, single link B/D/F, when bit0=1,
-+ * master link B/D/F
-+ */
-+ params.acConfig.ucLinkSel = 1;
-+
-+ if (ENGINE_ID_DIGB == cntl->engine_id)
-+ /* Bit3: Transmitter data source selection
-+ * =0 DIGA is data source.
-+ * =1 DIGB is data source.
-+ * This bit is only useful when ucAction= ATOM_ENABLE
-+ */
-+ params.acConfig.ucEncoderSel = 1;
-+
-+ if (CONNECTOR_ID_DISPLAY_PORT == connector_id)
-+ /* Bit4: DP connector flag
-+ * =0 connector is none-DP connector
-+ * =1 connector is DP connector
-+ */
-+ params.acConfig.fDPConnector = 1;
-+
-+ /* Bit[7:6]: Transmitter selection
-+ * =0 UNIPHY_ENCODER: UNIPHYA/B
-+ * =1 UNIPHY1_ENCODER: UNIPHYC/D
-+ * =2 UNIPHY2_ENCODER: UNIPHYE/F
-+ * =3 reserved
-+ */
-+ params.acConfig.ucTransmitterSel =
-+ (uint8_t)bp->cmd_helper->transmitter_bp_to_atom(
-+ cntl->transmitter);
-+
-+ params.ucAction = (uint8_t)cntl->action;
-+
-+ if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+static enum bp_result transmitter_control_v3(
-+ struct bios_parser *bp,
-+ struct bp_transmitter_control *cntl)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 params;
-+ uint32_t pll_id;
-+ enum connector_id conn_id =
-+ dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
-+ const struct command_table_helper *cmd = bp->cmd_helper;
-+ bool dual_link_conn = (CONNECTOR_ID_DUAL_LINK_DVII == conn_id)
-+ || (CONNECTOR_ID_DUAL_LINK_DVID == conn_id);
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+
-+ switch (cntl->transmitter) {
-+ case TRANSMITTER_UNIPHY_A:
-+ case TRANSMITTER_UNIPHY_B:
-+ case TRANSMITTER_UNIPHY_C:
-+ case TRANSMITTER_UNIPHY_D:
-+ case TRANSMITTER_UNIPHY_E:
-+ case TRANSMITTER_UNIPHY_F:
-+ case TRANSMITTER_TRAVIS_LCD:
-+ break;
-+ default:
-+ return BP_RESULT_BADINPUT;
-+ }
-+
-+ if (!cmd->clock_source_id_to_atom(cntl->pll_id, &pll_id))
-+ return BP_RESULT_BADINPUT;
-+
-+ /* fill information based on the action */
-+ switch (cntl->action) {
-+ case TRANSMITTER_CONTROL_INIT:
-+ if (dual_link_conn) {
-+ /* on INIT this bit should be set according to the
-+ * phisycal connector
-+ * Bit0: dual link connector flag
-+ * =0 connector is single link connector
-+ * =1 connector is dual link connector
-+ */
-+ params.acConfig.fDualLinkConnector = 1;
-+ }
-+
-+ /* connector object id */
-+ params.usInitInfo =
-+ cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
-+ break;
-+ case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
-+ /* votage swing and pre-emphsis */
-+ params.asMode.ucLaneSel = (uint8_t)cntl->lane_select;
-+ params.asMode.ucLaneSet = (uint8_t)cntl->lane_settings;
-+ break;
-+ default:
-+ if (dual_link_conn && cntl->multi_path)
-+ /* on ENABLE/DISABLE this bit should be set according to
-+ * actual timing (number of lanes)
-+ * Bit0: dual link connector flag
-+ * =0 connector is single link connector
-+ * =1 connector is dual link connector
-+ */
-+ params.acConfig.fDualLinkConnector = 1;
-+
-+ /* if dual-link */
-+ if (LANE_COUNT_FOUR < cntl->lanes_number) {
-+ /* on ENABLE/DISABLE this bit should be set according to
-+ * actual timing (number of lanes)
-+ * Bit0: dual link connector flag
-+ * =0 connector is single link connector
-+ * =1 connector is dual link connector
-+ */
-+ params.acConfig.fDualLinkConnector = 1;
-+
-+ /* link rate, half for dual link
-+ * We need to convert from KHz units into 20KHz units
-+ */
-+ params.usPixelClock =
-+ cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
-+ } else {
-+ /* link rate, half for dual link
-+ * We need to convert from KHz units into 10KHz units
-+ */
-+ params.usPixelClock =
-+ cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
-+ if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-+ switch (cntl->color_depth) {
-+ case COLOR_DEPTH_101010:
-+ params.usPixelClock =
-+ cpu_to_le16((le16_to_cpu(params.usPixelClock) * 30) / 24);
-+ break;
-+ case COLOR_DEPTH_121212:
-+ params.usPixelClock =
-+ cpu_to_le16((le16_to_cpu(params.usPixelClock) * 36) / 24);
-+ break;
-+ case COLOR_DEPTH_161616:
-+ params.usPixelClock =
-+ cpu_to_le16((le16_to_cpu(params.usPixelClock) * 48) / 24);
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ break;
-+ }
-+
-+ /* 00 - coherent mode
-+ * 01 - incoherent mode
-+ */
-+
-+ params.acConfig.fCoherentMode = cntl->coherent;
-+
-+ if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
-+ || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
-+ || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
-+ /* Bit2: Transmitter Link selection
-+ * =0 when bit0=0, single link A/C/E, when bit0=1,
-+ * master link A/C/E
-+ * =1 when bit0=0, single link B/D/F, when bit0=1,
-+ * master link B/D/F
-+ */
-+ params.acConfig.ucLinkSel = 1;
-+
-+ if (ENGINE_ID_DIGB == cntl->engine_id)
-+ /* Bit3: Transmitter data source selection
-+ * =0 DIGA is data source.
-+ * =1 DIGB is data source.
-+ * This bit is only useful when ucAction= ATOM_ENABLE
-+ */
-+ params.acConfig.ucEncoderSel = 1;
-+
-+ /* Bit[7:6]: Transmitter selection
-+ * =0 UNIPHY_ENCODER: UNIPHYA/B
-+ * =1 UNIPHY1_ENCODER: UNIPHYC/D
-+ * =2 UNIPHY2_ENCODER: UNIPHYE/F
-+ * =3 reserved
-+ */
-+ params.acConfig.ucTransmitterSel =
-+ (uint8_t)cmd->transmitter_bp_to_atom(cntl->transmitter);
-+
-+ params.ucLaneNum = (uint8_t)cntl->lanes_number;
-+
-+ params.acConfig.ucRefClkSource = (uint8_t)pll_id;
-+
-+ params.ucAction = (uint8_t)cntl->action;
-+
-+ if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+static enum bp_result transmitter_control_v4(
-+ struct bios_parser *bp,
-+ struct bp_transmitter_control *cntl)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 params;
-+ uint32_t ref_clk_src_id;
-+ enum connector_id conn_id =
-+ dal_graphics_object_id_get_connector_id(cntl->connector_obj_id);
-+ const struct command_table_helper *cmd = bp->cmd_helper;
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+
-+ switch (cntl->transmitter) {
-+ case TRANSMITTER_UNIPHY_A:
-+ case TRANSMITTER_UNIPHY_B:
-+ case TRANSMITTER_UNIPHY_C:
-+ case TRANSMITTER_UNIPHY_D:
-+ case TRANSMITTER_UNIPHY_E:
-+ case TRANSMITTER_UNIPHY_F:
-+ case TRANSMITTER_TRAVIS_LCD:
-+ break;
-+ default:
-+ return BP_RESULT_BADINPUT;
-+ }
-+
-+ if (!cmd->clock_source_id_to_ref_clk_src(cntl->pll_id, &ref_clk_src_id))
-+ return BP_RESULT_BADINPUT;
-+
-+ switch (cntl->action) {
-+ case TRANSMITTER_CONTROL_INIT:
-+ {
-+ if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
-+ (CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
-+ /* on INIT this bit should be set according to the
-+ * phisycal connector
-+ * Bit0: dual link connector flag
-+ * =0 connector is single link connector
-+ * =1 connector is dual link connector
-+ */
-+ params.acConfig.fDualLinkConnector = 1;
-+
-+ /* connector object id */
-+ params.usInitInfo =
-+ cpu_to_le16((uint8_t)(cntl->connector_obj_id.id));
-+ }
-+ break;
-+ case TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS:
-+ /* votage swing and pre-emphsis */
-+ params.asMode.ucLaneSel = (uint8_t)(cntl->lane_select);
-+ params.asMode.ucLaneSet = (uint8_t)(cntl->lane_settings);
-+ break;
-+ default:
-+ if ((CONNECTOR_ID_DUAL_LINK_DVII == conn_id) ||
-+ (CONNECTOR_ID_DUAL_LINK_DVID == conn_id))
-+ /* on ENABLE/DISABLE this bit should be set according to
-+ * actual timing (number of lanes)
-+ * Bit0: dual link connector flag
-+ * =0 connector is single link connector
-+ * =1 connector is dual link connector
-+ */
-+ params.acConfig.fDualLinkConnector = 1;
-+
-+ /* if dual-link */
-+ if (LANE_COUNT_FOUR < cntl->lanes_number)
-+ /* link rate, half for dual link
-+ * We need to convert from KHz units into 20KHz units
-+ */
-+ params.usPixelClock =
-+ cpu_to_le16((uint16_t)(cntl->pixel_clock / 20));
-+ else {
-+ /* link rate, half for dual link
-+ * We need to convert from KHz units into 10KHz units
-+ */
-+ params.usPixelClock =
-+ cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
-+
-+ if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-+ switch (cntl->color_depth) {
-+ case COLOR_DEPTH_101010:
-+ params.usPixelClock =
-+ cpu_to_le16((le16_to_cpu(params.usPixelClock) * 30) / 24);
-+ break;
-+ case COLOR_DEPTH_121212:
-+ params.usPixelClock =
-+ cpu_to_le16((le16_to_cpu(params.usPixelClock) * 36) / 24);
-+ break;
-+ case COLOR_DEPTH_161616:
-+ params.usPixelClock =
-+ cpu_to_le16((le16_to_cpu(params.usPixelClock) * 48) / 24);
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ break;
-+ }
-+
-+ /* 00 - coherent mode
-+ * 01 - incoherent mode
-+ */
-+
-+ params.acConfig.fCoherentMode = cntl->coherent;
-+
-+ if ((TRANSMITTER_UNIPHY_B == cntl->transmitter)
-+ || (TRANSMITTER_UNIPHY_D == cntl->transmitter)
-+ || (TRANSMITTER_UNIPHY_F == cntl->transmitter))
-+ /* Bit2: Transmitter Link selection
-+ * =0 when bit0=0, single link A/C/E, when bit0=1,
-+ * master link A/C/E
-+ * =1 when bit0=0, single link B/D/F, when bit0=1,
-+ * master link B/D/F
-+ */
-+ params.acConfig.ucLinkSel = 1;
-+
-+ if (ENGINE_ID_DIGB == cntl->engine_id)
-+ /* Bit3: Transmitter data source selection
-+ * =0 DIGA is data source.
-+ * =1 DIGB is data source.
-+ * This bit is only useful when ucAction= ATOM_ENABLE
-+ */
-+ params.acConfig.ucEncoderSel = 1;
-+
-+ /* Bit[7:6]: Transmitter selection
-+ * =0 UNIPHY_ENCODER: UNIPHYA/B
-+ * =1 UNIPHY1_ENCODER: UNIPHYC/D
-+ * =2 UNIPHY2_ENCODER: UNIPHYE/F
-+ * =3 reserved
-+ */
-+ params.acConfig.ucTransmitterSel =
-+ (uint8_t)(cmd->transmitter_bp_to_atom(cntl->transmitter));
-+ params.ucLaneNum = (uint8_t)(cntl->lanes_number);
-+ params.acConfig.ucRefClkSource = (uint8_t)(ref_clk_src_id);
-+ params.ucAction = (uint8_t)(cntl->action);
-+
-+ if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+static enum bp_result transmitter_control_v1_5(
-+ struct bios_parser *bp,
-+ struct bp_transmitter_control *cntl)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ const struct command_table_helper *cmd = bp->cmd_helper;
-+ DIG_TRANSMITTER_CONTROL_PARAMETERS_V1_5 params;
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+ params.ucPhyId = cmd->phy_id_to_atom(cntl->transmitter);
-+ params.ucAction = (uint8_t)cntl->action;
-+ params.ucLaneNum = (uint8_t)cntl->lanes_number;
-+ params.ucConnObjId = (uint8_t)cntl->connector_obj_id.id;
-+
-+ params.ucDigMode =
-+ cmd->signal_type_to_atom_dig_mode(cntl->signal);
-+ params.asConfig.ucPhyClkSrcId =
-+ cmd->clock_source_id_to_atom_phy_clk_src_id(cntl->pll_id);
-+ /* 00 - coherent mode */
-+ params.asConfig.ucCoherentMode = cntl->coherent;
-+ params.asConfig.ucHPDSel =
-+ cmd->hpd_sel_to_atom(cntl->hpd_sel);
-+ params.ucDigEncoderSel =
-+ cmd->dig_encoder_sel_to_atom(cntl->engine_id);
-+ params.ucDPLaneSet = (uint8_t) cntl->lane_settings;
-+ params.usSymClock = cpu_to_le16((uint16_t) (cntl->pixel_clock / 10));
-+ /*
-+ * In SI/TN case, caller have to set usPixelClock as following:
-+ * DP mode: usPixelClock = DP_LINK_CLOCK/10
-+ * (DP_LINK_CLOCK = 1.62GHz, 2.7GHz, 5.4GHz)
-+ * DVI single link mode: usPixelClock = pixel clock
-+ * DVI dual link mode: usPixelClock = pixel clock
-+ * HDMI mode: usPixelClock = pixel clock * deep_color_ratio
-+ * (=1: 8bpp, =1.25: 10bpp, =1.5:12bpp, =2: 16bpp)
-+ * LVDS mode: usPixelClock = pixel clock
-+ */
-+ switch (cntl->signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ switch (cntl->color_depth) {
-+ case COLOR_DEPTH_101010:
-+ params.usSymClock =
-+ cpu_to_le16((le16_to_cpu(params.usSymClock) * 30) / 24);
-+ break;
-+ case COLOR_DEPTH_121212:
-+ params.usSymClock =
-+ cpu_to_le16((le16_to_cpu(params.usSymClock) * 36) / 24);
-+ break;
-+ case COLOR_DEPTH_161616:
-+ params.usSymClock =
-+ cpu_to_le16((le16_to_cpu(params.usSymClock) * 48) / 24);
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (EXEC_BIOS_CMD_TABLE(UNIPHYTransmitterControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** SET PIXEL CLOCK
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result set_pixel_clock_v3(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params);
-+static enum bp_result set_pixel_clock_v5(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params);
-+static enum bp_result set_pixel_clock_v6(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params);
-+
-+static void init_set_pixel_clock(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
-+ case 3:
-+ bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v3;
-+ break;
-+ case 5:
-+ bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v5;
-+ break;
-+ case 6:
-+ bp->cmd_tbl.set_pixel_clock = set_pixel_clock_v6;
-+ break;
-+ default:
-+ bp->cmd_tbl.set_pixel_clock = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result set_pixel_clock_v3(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ PIXEL_CLOCK_PARAMETERS_V3 *params;
-+ SET_PIXEL_CLOCK_PS_ALLOCATION allocation;
-+
-+ dc_service_memset(&allocation, 0, sizeof(allocation));
-+
-+ if (CLOCK_SOURCE_ID_PLL1 == bp_params->pll_id)
-+ allocation.sPCLKInput.ucPpll = ATOM_PPLL1;
-+ else if (CLOCK_SOURCE_ID_PLL2 == bp_params->pll_id)
-+ allocation.sPCLKInput.ucPpll = ATOM_PPLL2;
-+ else
-+ return BP_RESULT_BADINPUT;
-+
-+ allocation.sPCLKInput.usRefDiv =
-+ cpu_to_le16((uint16_t)bp_params->reference_divider);
-+ allocation.sPCLKInput.usFbDiv =
-+ cpu_to_le16((uint16_t)bp_params->feedback_divider);
-+ allocation.sPCLKInput.ucFracFbDiv =
-+ (uint8_t)bp_params->fractional_feedback_divider;
-+ allocation.sPCLKInput.ucPostDiv =
-+ (uint8_t)bp_params->pixel_clock_post_divider;
-+
-+ /* We need to convert from KHz units into 10KHz units */
-+ allocation.sPCLKInput.usPixelClock =
-+ cpu_to_le16((uint16_t)(bp_params->target_pixel_clock / 10));
-+
-+ params = (PIXEL_CLOCK_PARAMETERS_V3 *)&allocation.sPCLKInput;
-+ params->ucTransmitterId =
-+ bp->cmd_helper->encoder_id_to_atom(
-+ dal_graphics_object_id_get_encoder_id(
-+ bp_params->encoder_object_id));
-+ params->ucEncoderMode =
-+ (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
-+ bp_params->signal_type, false));
-+
-+ if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
-+ params->ucMiscInfo |= PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
-+
-+ if (bp_params->flags.USE_E_CLOCK_AS_SOURCE_FOR_D_CLOCK)
-+ params->ucMiscInfo |= PIXEL_CLOCK_MISC_USE_ENGINE_FOR_DISPCLK;
-+
-+ if (CONTROLLER_ID_D1 != bp_params->controller_id)
-+ params->ucMiscInfo |= PIXEL_CLOCK_MISC_CRTC_SEL_CRTC2;
-+
-+ if (EXEC_BIOS_CMD_TABLE(SetPixelClock, allocation))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+#ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V5
-+/* video bios did not define this: */
-+typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V5 {
-+ PIXEL_CLOCK_PARAMETERS_V5 sPCLKInput;
-+ /* Caller doesn't need to init this portion */
-+ ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
-+} SET_PIXEL_CLOCK_PS_ALLOCATION_V5;
-+#endif
-+
-+#ifndef SET_PIXEL_CLOCK_PS_ALLOCATION_V6
-+/* video bios did not define this: */
-+typedef struct _SET_PIXEL_CLOCK_PS_ALLOCATION_V6 {
-+ PIXEL_CLOCK_PARAMETERS_V6 sPCLKInput;
-+ /* Caller doesn't need to init this portion */
-+ ENABLE_SPREAD_SPECTRUM_ON_PPLL sReserved;
-+} SET_PIXEL_CLOCK_PS_ALLOCATION_V6;
-+#endif
-+
-+static enum bp_result set_pixel_clock_v5(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ SET_PIXEL_CLOCK_PS_ALLOCATION_V5 clk;
-+ uint8_t controller_id;
-+ uint32_t pll_id;
-+
-+ dc_service_memset(&clk, 0, sizeof(clk));
-+
-+ if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
-+ && bp->cmd_helper->controller_id_to_atom(
-+ bp_params->controller_id, &controller_id)) {
-+ clk.sPCLKInput.ucCRTC = controller_id;
-+ clk.sPCLKInput.ucPpll = (uint8_t)pll_id;
-+ clk.sPCLKInput.ucRefDiv =
-+ (uint8_t)(bp_params->reference_divider);
-+ clk.sPCLKInput.usFbDiv =
-+ cpu_to_le16((uint16_t)(bp_params->feedback_divider));
-+ clk.sPCLKInput.ulFbDivDecFrac =
-+ cpu_to_le32(bp_params->fractional_feedback_divider);
-+ clk.sPCLKInput.ucPostDiv =
-+ (uint8_t)(bp_params->pixel_clock_post_divider);
-+ clk.sPCLKInput.ucTransmitterID =
-+ bp->cmd_helper->encoder_id_to_atom(
-+ dal_graphics_object_id_get_encoder_id(
-+ bp_params->encoder_object_id));
-+ clk.sPCLKInput.ucEncoderMode =
-+ (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
-+ bp_params->signal_type, false);
-+
-+ /* We need to convert from KHz units into 10KHz units */
-+ clk.sPCLKInput.usPixelClock =
-+ cpu_to_le16((uint16_t)(bp_params->target_pixel_clock / 10));
-+
-+ if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL)
-+ clk.sPCLKInput.ucMiscInfo |=
-+ PIXEL_CLOCK_MISC_FORCE_PROG_PPLL;
-+
-+ if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
-+ clk.sPCLKInput.ucMiscInfo |=
-+ PIXEL_CLOCK_MISC_REF_DIV_SRC;
-+
-+ /* clkV5.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0: 24bpp
-+ * =1:30bpp, =2:32bpp
-+ * driver choose program it itself, i.e. here we program it
-+ * to 888 by default.
-+ */
-+
-+ if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
-+ result = BP_RESULT_OK;
-+ }
-+
-+ return result;
-+}
-+
-+static enum bp_result set_pixel_clock_v6(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ SET_PIXEL_CLOCK_PS_ALLOCATION_V6 clk;
-+ uint8_t controller_id;
-+ uint32_t pll_id;
-+
-+ dc_service_memset(&clk, 0, sizeof(clk));
-+
-+ if (bp->cmd_helper->clock_source_id_to_atom(bp_params->pll_id, &pll_id)
-+ && bp->cmd_helper->controller_id_to_atom(
-+ bp_params->controller_id, &controller_id)) {
-+ /* Note: VBIOS still wants to use ucCRTC name which is now
-+ * 1 byte in ULONG
-+ *typedef struct _CRTC_PIXEL_CLOCK_FREQ
-+ *{
-+ * target the pixel clock to drive the CRTC timing.
-+ * ULONG ulPixelClock:24;
-+ * 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to
-+ * previous version.
-+ * ATOM_CRTC1~6, indicate the CRTC controller to
-+ * ULONG ucCRTC:8;
-+ * drive the pixel clock. not used for DCPLL case.
-+ *}CRTC_PIXEL_CLOCK_FREQ;
-+ *union
-+ *{
-+ * pixel clock and CRTC id frequency
-+ * CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq;
-+ * ULONG ulDispEngClkFreq; dispclk frequency
-+ *};
-+ */
-+ clk.sPCLKInput.ulCrtcPclkFreq.ucCRTC = controller_id;
-+ clk.sPCLKInput.ucPpll = (uint8_t) pll_id;
-+ clk.sPCLKInput.ucRefDiv =
-+ (uint8_t) bp_params->reference_divider;
-+ clk.sPCLKInput.usFbDiv =
-+ cpu_to_le16((uint16_t) bp_params->feedback_divider);
-+ clk.sPCLKInput.ulFbDivDecFrac =
-+ cpu_to_le32(bp_params->fractional_feedback_divider);
-+ clk.sPCLKInput.ucPostDiv =
-+ (uint8_t) bp_params->pixel_clock_post_divider;
-+ clk.sPCLKInput.ucTransmitterID =
-+ bp->cmd_helper->encoder_id_to_atom(
-+ dal_graphics_object_id_get_encoder_id(
-+ bp_params->encoder_object_id));
-+ clk.sPCLKInput.ucEncoderMode =
-+ (uint8_t) bp->cmd_helper->encoder_mode_bp_to_atom(
-+ bp_params->signal_type, false);
-+
-+ /* We need to convert from KHz units into 10KHz units */
-+ clk.sPCLKInput.ulCrtcPclkFreq.ulPixelClock =
-+ cpu_to_le32(bp_params->target_pixel_clock / 10);
-+
-+ if (bp_params->flags.FORCE_PROGRAMMING_OF_PLL) {
-+ clk.sPCLKInput.ucMiscInfo |=
-+ PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL;
-+ }
-+
-+ if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC) {
-+ clk.sPCLKInput.ucMiscInfo |=
-+ PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
-+ }
-+
-+ /* clkV6.ucMiscInfo bit[3:2]= HDMI panel bit depth: =0:
-+ * 24bpp =1:30bpp, =2:32bpp
-+ * driver choose program it itself, i.e. here we pass required
-+ * target rate that includes deep color.
-+ */
-+
-+ if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk))
-+ result = BP_RESULT_OK;
-+ }
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** ENABLE PIXEL CLOCK SS
-+**
-+********************************************************************************
-+*******************************************************************************/
-+static enum bp_result enable_spread_spectrum_on_ppll_v1(
-+ struct bios_parser *bp,
-+ struct bp_spread_spectrum_parameters *bp_params,
-+ bool enable);
-+static enum bp_result enable_spread_spectrum_on_ppll_v2(
-+ struct bios_parser *bp,
-+ struct bp_spread_spectrum_parameters *bp_params,
-+ bool enable);
-+static enum bp_result enable_spread_spectrum_on_ppll_v3(
-+ struct bios_parser *bp,
-+ struct bp_spread_spectrum_parameters *bp_params,
-+ bool enable);
-+
-+static void init_enable_spread_spectrum_on_ppll(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(EnableSpreadSpectrumOnPPLL)) {
-+ case 1:
-+ bp->cmd_tbl.enable_spread_spectrum_on_ppll =
-+ enable_spread_spectrum_on_ppll_v1;
-+ break;
-+ case 2:
-+ bp->cmd_tbl.enable_spread_spectrum_on_ppll =
-+ enable_spread_spectrum_on_ppll_v2;
-+ break;
-+ case 3:
-+ bp->cmd_tbl.enable_spread_spectrum_on_ppll =
-+ enable_spread_spectrum_on_ppll_v3;
-+ break;
-+ default:
-+ bp->cmd_tbl.enable_spread_spectrum_on_ppll = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result enable_spread_spectrum_on_ppll_v1(
-+ struct bios_parser *bp,
-+ struct bp_spread_spectrum_parameters *bp_params,
-+ bool enable)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ ENABLE_SPREAD_SPECTRUM_ON_PPLL params;
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+
-+ if ((enable == true) && (bp_params->percentage > 0))
-+ params.ucEnable = ATOM_ENABLE;
-+ else
-+ params.ucEnable = ATOM_DISABLE;
-+
-+ params.usSpreadSpectrumPercentage =
-+ cpu_to_le16((uint16_t)bp_params->percentage);
-+ params.ucSpreadSpectrumStep =
-+ (uint8_t)bp_params->ver1.step;
-+ params.ucSpreadSpectrumDelay =
-+ (uint8_t)bp_params->ver1.delay;
-+ /* convert back to unit of 10KHz */
-+ params.ucSpreadSpectrumRange =
-+ (uint8_t)(bp_params->ver1.range / 10000);
-+
-+ if (bp_params->flags.EXTERNAL_SS)
-+ params.ucSpreadSpectrumType |= ATOM_EXTERNAL_SS_MASK;
-+
-+ if (bp_params->flags.CENTER_SPREAD)
-+ params.ucSpreadSpectrumType |= ATOM_SS_CENTRE_SPREAD_MODE;
-+
-+ if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
-+ params.ucPpll = ATOM_PPLL1;
-+ else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
-+ params.ucPpll = ATOM_PPLL2;
-+ else
-+ BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
-+
-+ if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+static enum bp_result enable_spread_spectrum_on_ppll_v2(
-+ struct bios_parser *bp,
-+ struct bp_spread_spectrum_parameters *bp_params,
-+ bool enable)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 params;
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+
-+ if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL1)
-+ params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P1PLL;
-+ else if (bp_params->pll_id == CLOCK_SOURCE_ID_PLL2)
-+ params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V2_P2PLL;
-+ else
-+ BREAK_TO_DEBUGGER(); /* Unexpected PLL value!! */
-+
-+ if ((enable == true) && (bp_params->percentage > 0)) {
-+ params.ucEnable = ATOM_ENABLE;
-+
-+ params.usSpreadSpectrumPercentage =
-+ cpu_to_le16((uint16_t)(bp_params->percentage));
-+ params.usSpreadSpectrumStep =
-+ cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
-+
-+ if (bp_params->flags.EXTERNAL_SS)
-+ params.ucSpreadSpectrumType |=
-+ ATOM_PPLL_SS_TYPE_V2_EXT_SPREAD;
-+
-+ if (bp_params->flags.CENTER_SPREAD)
-+ params.ucSpreadSpectrumType |=
-+ ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD;
-+
-+ /* Both amounts need to be left shifted first before bit
-+ * comparison. Otherwise, the result will always be zero here
-+ */
-+ params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
-+ ((bp_params->ds.feedback_amount <<
-+ ATOM_PPLL_SS_AMOUNT_V2_FBDIV_SHIFT) &
-+ ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK) |
-+ ((bp_params->ds.nfrac_amount <<
-+ ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
-+ ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK)));
-+ } else
-+ params.ucEnable = ATOM_DISABLE;
-+
-+ if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+static enum bp_result enable_spread_spectrum_on_ppll_v3(
-+ struct bios_parser *bp,
-+ struct bp_spread_spectrum_parameters *bp_params,
-+ bool enable)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 params;
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+
-+ switch (bp_params->pll_id) {
-+ case CLOCK_SOURCE_ID_PLL0:
-+ /* ATOM_PPLL_SS_TYPE_V3_P0PLL; this is pixel clock only,
-+ * not for SI display clock.
-+ */
-+ params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
-+ break;
-+ case CLOCK_SOURCE_ID_PLL1:
-+ params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P1PLL;
-+ break;
-+
-+ case CLOCK_SOURCE_ID_PLL2:
-+ params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_P2PLL;
-+ break;
-+
-+ case CLOCK_SOURCE_ID_DCPLL:
-+ params.ucSpreadSpectrumType = ATOM_PPLL_SS_TYPE_V3_DCPLL;
-+ break;
-+
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ /* Unexpected PLL value!! */
-+ return result;
-+ }
-+
-+ if (enable == true) {
-+ params.ucEnable = ATOM_ENABLE;
-+
-+ params.usSpreadSpectrumAmountFrac =
-+ cpu_to_le16((uint16_t)(bp_params->ds_frac_amount));
-+ params.usSpreadSpectrumStep =
-+ cpu_to_le16((uint16_t)(bp_params->ds.ds_frac_size));
-+
-+ if (bp_params->flags.EXTERNAL_SS)
-+ params.ucSpreadSpectrumType |=
-+ ATOM_PPLL_SS_TYPE_V3_EXT_SPREAD;
-+ if (bp_params->flags.CENTER_SPREAD)
-+ params.ucSpreadSpectrumType |=
-+ ATOM_PPLL_SS_TYPE_V3_CENTRE_SPREAD;
-+
-+ /* Both amounts need to be left shifted first before bit
-+ * comparison. Otherwise, the result will always be zero here
-+ */
-+ params.usSpreadSpectrumAmount = cpu_to_le16((uint16_t)(
-+ ((bp_params->ds.feedback_amount <<
-+ ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT) &
-+ ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK) |
-+ ((bp_params->ds.nfrac_amount <<
-+ ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT) &
-+ ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK)));
-+ } else
-+ params.ucEnable = ATOM_DISABLE;
-+
-+ if (EXEC_BIOS_CMD_TABLE(EnableSpreadSpectrumOnPPLL, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** ADJUST DISPLAY PLL
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result adjust_display_pll_v2(
-+ struct bios_parser *bp,
-+ struct bp_adjust_pixel_clock_parameters *bp_params);
-+static enum bp_result adjust_display_pll_v3(
-+ struct bios_parser *bp,
-+ struct bp_adjust_pixel_clock_parameters *bp_params);
-+
-+static void init_adjust_display_pll(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll)) {
-+ case 2:
-+ bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v2;
-+ break;
-+ case 3:
-+ bp->cmd_tbl.adjust_display_pll = adjust_display_pll_v3;
-+ break;
-+ default:
-+ bp->cmd_tbl.adjust_display_pll = NULL;
-+ break;
-+ }
-+}
-+
-+static bool adjust_display_pll_bug_patch(ADJUST_DISPLAY_PLL_PARAMETERS *params)
-+{
-+ /* vbios bug: pixel clock should not be doubled for DVO with 24bit
-+ * interface */
-+ if ((params->ucTransmitterID == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
-+ && (params->ucDVOConfig == DVO_ENCODER_CONFIG_24BIT))
-+ /* the current pixel clock is good. no adjustment is required */
-+ return true;
-+ return false;
-+}
-+
-+static enum bp_result adjust_display_pll_v2(
-+ struct bios_parser *bp,
-+ struct bp_adjust_pixel_clock_parameters *bp_params)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ ADJUST_DISPLAY_PLL_PS_ALLOCATION params = { 0 };
-+
-+ /* We need to convert from KHz units into 10KHz units and then convert
-+ * output pixel clock back 10KHz-->KHz */
-+ uint32_t pixel_clock_10KHz_in = bp_params->pixel_clock / 10;
-+
-+ params.usPixelClock = cpu_to_le16((uint16_t)(pixel_clock_10KHz_in));
-+ params.ucTransmitterID =
-+ bp->cmd_helper->encoder_id_to_atom(
-+ dal_graphics_object_id_get_encoder_id(
-+ bp_params->encoder_object_id));
-+ params.ucEncodeMode =
-+ (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
-+ bp_params->signal_type, false);
-+ params.ucDVOConfig = (uint8_t)(bp_params->dvo_config);
-+
-+ if (adjust_display_pll_bug_patch(&params)
-+ || EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) {
-+ /* Convert output pixel clock back 10KHz-->KHz: multiply
-+ * original pixel clock in KHz by ratio
-+ * [output pxlClk/input pxlClk] */
-+ uint64_t pixel_clock_10KHz_out =
-+ le16_to_cpu((uint64_t)params.usPixelClock);
-+ uint64_t pixel_clock = (uint64_t)bp_params->pixel_clock;
-+
-+ bp_params->adjusted_pixel_clock =
-+ div_u64(pixel_clock * pixel_clock_10KHz_out,
-+ pixel_clock_10KHz_in);
-+ result = BP_RESULT_OK;
-+ }
-+
-+ return result;
-+}
-+
-+static enum bp_result adjust_display_pll_v3(
-+ struct bios_parser *bp,
-+ struct bp_adjust_pixel_clock_parameters *bp_params)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ ADJUST_DISPLAY_PLL_PS_ALLOCATION_V3 params;
-+ uint32_t pixel_clk_10_kHz_in = bp_params->pixel_clock / 10;
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+
-+ /* We need to convert from KHz units into 10KHz units and then convert
-+ * output pixel clock back 10KHz-->KHz */
-+ params.sInput.usPixelClock = cpu_to_le16((uint16_t)pixel_clk_10_kHz_in);
-+ params.sInput.ucTransmitterID =
-+ bp->cmd_helper->encoder_id_to_atom(
-+ dal_graphics_object_id_get_encoder_id(
-+ bp_params->encoder_object_id));
-+ params.sInput.ucEncodeMode =
-+ (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
-+ bp_params->signal_type, false);
-+
-+ if (DISP_PLL_CONFIG_DVO_DDR_MODE_LOW_12BIT ==
-+ bp_params->display_pll_config)
-+ params.sInput.ucDispPllConfig =
-+ DISPPLL_CONFIG_DVO_DDR_SPEED |
-+ DISPPLL_CONFIG_DVO_LOW12BIT;
-+ else if (DISP_PLL_CONFIG_DVO_DDR_MODE_UPPER_12BIT ==
-+ bp_params->display_pll_config)
-+ params.sInput.ucDispPllConfig =
-+ DISPPLL_CONFIG_DVO_DDR_SPEED |
-+ DISPPLL_CONFIG_DVO_UPPER12BIT;
-+ else if (DISP_PLL_CONFIG_DVO_DDR_MODE_24BIT ==
-+ bp_params->display_pll_config)
-+ params.sInput.ucDispPllConfig =
-+ DISPPLL_CONFIG_DVO_DDR_SPEED | DISPPLL_CONFIG_DVO_24BIT;
-+ else
-+ /* this does not mean anything here */
-+ params.sInput.ucDispPllConfig =
-+ (uint8_t)(bp_params->display_pll_config);
-+
-+ if (bp_params->ss_enable == true)
-+ params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_SS_ENABLE;
-+
-+ if (bp_params->signal_type == SIGNAL_TYPE_DVI_DUAL_LINK)
-+ params.sInput.ucDispPllConfig |= DISPPLL_CONFIG_DUAL_LINK;
-+
-+ if (EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params)) {
-+ /* Convert output pixel clock back 10KHz-->KHz: multiply
-+ * original pixel clock in KHz by ratio
-+ * [output pxlClk/input pxlClk] */
-+ uint64_t pixel_clk_10_khz_out =
-+ (uint64_t)le32_to_cpu(params.sOutput.ulDispPllFreq);
-+ uint64_t pixel_clk = (uint64_t)bp_params->pixel_clock;
-+
-+ if (pixel_clk_10_kHz_in != 0) {
-+ bp_params->adjusted_pixel_clock =
-+ div_u64(pixel_clk * pixel_clk_10_khz_out,
-+ pixel_clk_10_kHz_in);
-+ } else {
-+ bp_params->adjusted_pixel_clock = 0;
-+ BREAK_TO_DEBUGGER();
-+ }
-+
-+ bp_params->reference_divider = params.sOutput.ucRefDiv;
-+ bp_params->pixel_clock_post_divider = params.sOutput.ucPostDiv;
-+
-+ result = BP_RESULT_OK;
-+ }
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** DAC ENCODER CONTROL
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result dac1_encoder_control_v1(
-+ struct bios_parser *bp,
-+ bool enable,
-+ uint32_t pixel_clock,
-+ uint8_t dac_standard);
-+static enum bp_result dac2_encoder_control_v1(
-+ struct bios_parser *bp,
-+ bool enable,
-+ uint32_t pixel_clock,
-+ uint8_t dac_standard);
-+
-+static void init_dac_encoder_control(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1EncoderControl)) {
-+ case 1:
-+ bp->cmd_tbl.dac1_encoder_control = dac1_encoder_control_v1;
-+ break;
-+ default:
-+ bp->cmd_tbl.dac1_encoder_control = NULL;
-+ break;
-+ }
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2EncoderControl)) {
-+ case 1:
-+ bp->cmd_tbl.dac2_encoder_control = dac2_encoder_control_v1;
-+ break;
-+ default:
-+ bp->cmd_tbl.dac2_encoder_control = NULL;
-+ break;
-+ }
-+}
-+
-+static void dac_encoder_control_prepare_params(
-+ DAC_ENCODER_CONTROL_PS_ALLOCATION *params,
-+ bool enable,
-+ uint32_t pixel_clock,
-+ uint8_t dac_standard)
-+{
-+ params->ucDacStandard = dac_standard;
-+ if (enable)
-+ params->ucAction = ATOM_ENABLE;
-+ else
-+ params->ucAction = ATOM_DISABLE;
-+
-+ /* We need to convert from KHz units into 10KHz units
-+ * it looks as if the TvControl do not care about pixel clock
-+ */
-+ params->usPixelClock = cpu_to_le16((uint16_t)(pixel_clock / 10));
-+}
-+
-+static enum bp_result dac1_encoder_control_v1(
-+ struct bios_parser *bp,
-+ bool enable,
-+ uint32_t pixel_clock,
-+ uint8_t dac_standard)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ DAC_ENCODER_CONTROL_PS_ALLOCATION params;
-+
-+ dac_encoder_control_prepare_params(
-+ &params,
-+ enable,
-+ pixel_clock,
-+ dac_standard);
-+
-+ if (EXEC_BIOS_CMD_TABLE(DAC1EncoderControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+static enum bp_result dac2_encoder_control_v1(
-+ struct bios_parser *bp,
-+ bool enable,
-+ uint32_t pixel_clock,
-+ uint8_t dac_standard)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ DAC_ENCODER_CONTROL_PS_ALLOCATION params;
-+
-+ dac_encoder_control_prepare_params(
-+ &params,
-+ enable,
-+ pixel_clock,
-+ dac_standard);
-+
-+ if (EXEC_BIOS_CMD_TABLE(DAC2EncoderControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** DAC OUTPUT CONTROL
-+**
-+********************************************************************************
-+*******************************************************************************/
-+static enum bp_result dac1_output_control_v1(
-+ struct bios_parser *bp,
-+ bool enable);
-+static enum bp_result dac2_output_control_v1(
-+ struct bios_parser *bp,
-+ bool enable);
-+
-+static void init_dac_output_control(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(DAC1OutputControl)) {
-+ case 1:
-+ bp->cmd_tbl.dac1_output_control = dac1_output_control_v1;
-+ break;
-+ default:
-+ bp->cmd_tbl.dac1_output_control = NULL;
-+ break;
-+ }
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(DAC2OutputControl)) {
-+ case 1:
-+ bp->cmd_tbl.dac2_output_control = dac2_output_control_v1;
-+ break;
-+ default:
-+ bp->cmd_tbl.dac2_output_control = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result dac1_output_control_v1(
-+ struct bios_parser *bp, bool enable)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
-+
-+ if (enable)
-+ params.ucAction = ATOM_ENABLE;
-+ else
-+ params.ucAction = ATOM_DISABLE;
-+
-+ if (EXEC_BIOS_CMD_TABLE(DAC1OutputControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+static enum bp_result dac2_output_control_v1(
-+ struct bios_parser *bp, bool enable)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION params;
-+
-+ if (enable)
-+ params.ucAction = ATOM_ENABLE;
-+ else
-+ params.ucAction = ATOM_DISABLE;
-+
-+ if (EXEC_BIOS_CMD_TABLE(DAC2OutputControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** DAC LOAD DETECTION
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum signal_type dac_load_detection_v3(
-+ struct bios_parser *bp,
-+ struct graphics_object_id encoder,
-+ struct graphics_object_id connector,
-+ enum signal_type display_signal);
-+
-+static void init_dac_load_detection(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(DAC_LoadDetection)) {
-+ case 3:
-+ bp->cmd_tbl.dac_load_detection = dac_load_detection_v3;
-+ break;
-+ default:
-+ bp->cmd_tbl.dac_load_detection = NULL;
-+ break;
-+ }
-+}
-+
-+static enum signal_type dac_load_detection_v3(
-+ struct bios_parser *bp,
-+ struct graphics_object_id encoder,
-+ struct graphics_object_id connector,
-+ enum signal_type display_signal)
-+{
-+ DAC_LOAD_DETECTION_PS_ALLOCATION params;
-+ enum signal_type signal = SIGNAL_TYPE_NONE;
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+
-+ /* load detection is cupported for CRT, TV and CV */
-+ switch (display_signal) {
-+ case SIGNAL_TYPE_RGB:
-+ switch (dal_graphics_object_id_get_encoder_id(encoder)) {
-+ case ENCODER_ID_INTERNAL_DAC1:
-+ case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
-+ params.sDacload.usDeviceID =
-+ cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT);
-+ break;
-+ case ENCODER_ID_INTERNAL_DAC2:
-+ case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
-+ params.sDacload.usDeviceID =
-+ cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT);
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+ default:
-+ return signal;
-+ }
-+
-+ /* set the encoder to detect on */
-+ switch (dal_graphics_object_id_get_encoder_id(encoder)) {
-+ case ENCODER_ID_INTERNAL_DAC1:
-+ case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
-+ params.sDacload.ucDacType = ATOM_DAC_A;
-+ break;
-+ case ENCODER_ID_INTERNAL_DAC2:
-+ case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
-+ params.sDacload.ucDacType = ATOM_DAC_B;
-+ break;
-+ case ENCODER_ID_EXTERNAL_CH7303:
-+ params.sDacload.ucDacType = ATOM_EXT_DAC;
-+ break;
-+ default:
-+ return signal;
-+ }
-+
-+ if (!EXEC_BIOS_CMD_TABLE(DAC_LoadDetection, params))
-+ return signal;
-+#if defined(CONFIG_DRM_AMD_DAL_VBIOS_PRESENT)
-+ signal = bp->bios_helper->detect_sink(
-+ bp->ctx,
-+ encoder,
-+ connector,
-+ display_signal);
-+#else
-+ BREAK_TO_DEBUGGER(); /* VBios is needed */
-+#endif
-+
-+ return signal;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** BLANK CRTC
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result blank_crtc_v1(
-+ struct bios_parser *bp,
-+ struct bp_blank_crtc_parameters *bp_params,
-+ bool blank);
-+
-+static void init_blank_crtc(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(BlankCRTC)) {
-+ case 1:
-+ bp->cmd_tbl.blank_crtc = blank_crtc_v1;
-+ break;
-+ default:
-+ bp->cmd_tbl.blank_crtc = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result blank_crtc_v1(
-+ struct bios_parser *bp,
-+ struct bp_blank_crtc_parameters *bp_params,
-+ bool blank)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ BLANK_CRTC_PARAMETERS params = {0};
-+ uint8_t atom_controller_id;
-+
-+ if (bp->cmd_helper->controller_id_to_atom(bp_params->controller_id,
-+ &atom_controller_id)) {
-+ params.ucCRTC = (uint8_t)atom_controller_id;
-+
-+ if (blank)
-+ params.ucBlanking = ATOM_BLANKING;
-+ else
-+ params.ucBlanking = ATOM_BLANKING_OFF;
-+ params.usBlackColorRCr =
-+ cpu_to_le16((uint16_t)bp_params->black_color_rcr);
-+ params.usBlackColorGY =
-+ cpu_to_le16((uint16_t)bp_params->black_color_gy);
-+ params.usBlackColorBCb =
-+ cpu_to_le16((uint16_t)bp_params->black_color_bcb);
-+
-+ if (EXEC_BIOS_CMD_TABLE(BlankCRTC, params))
-+ result = BP_RESULT_OK;
-+ } else
-+ /* Not support more than two CRTC as current ASIC, update this
-+ * if needed.
-+ */
-+ result = BP_RESULT_BADINPUT;
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** SET CRTC TIMING
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result set_crtc_using_dtd_timing_v3(
-+ struct bios_parser *bp,
-+ struct bp_hw_crtc_timing_parameters *bp_params);
-+static enum bp_result set_crtc_timing_v1(
-+ struct bios_parser *bp,
-+ struct bp_hw_crtc_timing_parameters *bp_params);
-+
-+static void init_set_crtc_timing(struct bios_parser *bp)
-+{
-+ uint32_t dtd_version =
-+ BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_UsingDTDTiming);
-+ if (dtd_version > 2)
-+ switch (dtd_version) {
-+ case 3:
-+ bp->cmd_tbl.set_crtc_timing =
-+ set_crtc_using_dtd_timing_v3;
-+ break;
-+ default:
-+ bp->cmd_tbl.set_crtc_timing = NULL;
-+ break;
-+ }
-+ else
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_Timing)) {
-+ case 1:
-+ bp->cmd_tbl.set_crtc_timing = set_crtc_timing_v1;
-+ break;
-+ default:
-+ bp->cmd_tbl.set_crtc_timing = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result set_crtc_timing_v1(
-+ struct bios_parser *bp,
-+ struct bp_hw_crtc_timing_parameters *bp_params)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION params = {0};
-+ uint8_t atom_controller_id;
-+
-+ if (bp->cmd_helper->controller_id_to_atom(
-+ bp_params->controller_id, &atom_controller_id))
-+ params.ucCRTC = atom_controller_id;
-+
-+ params.usH_Total = cpu_to_le16((uint16_t)(bp_params->h_total));
-+ params.usH_Disp = cpu_to_le16((uint16_t)(bp_params->h_addressable));
-+ params.usH_SyncStart = cpu_to_le16((uint16_t)(bp_params->h_sync_start));
-+ params.usH_SyncWidth = cpu_to_le16((uint16_t)(bp_params->h_sync_width));
-+ params.usV_Total = cpu_to_le16((uint16_t)(bp_params->v_total));
-+ params.usV_Disp = cpu_to_le16((uint16_t)(bp_params->v_addressable));
-+ params.usV_SyncStart =
-+ cpu_to_le16((uint16_t)(bp_params->v_sync_start));
-+ params.usV_SyncWidth =
-+ cpu_to_le16((uint16_t)(bp_params->v_sync_width));
-+
-+
-+ /* VBIOS does not expect any value except zero into this call, for
-+ * underscan use another entry ProgramOverscan call but when mode
-+ * 1776x1000 with the overscan 72x44 .e.i. 1920x1080 @30 DAL2 is ok,
-+ * but when same ,but 60 Hz there is corruption
-+ * DAL1 does not allow the mode 1776x1000@60
-+ */
-+ params.ucOverscanRight = (uint8_t)bp_params->h_overscan_right;
-+ params.ucOverscanLeft = (uint8_t)bp_params->h_overscan_left;
-+ params.ucOverscanBottom = (uint8_t)bp_params->v_overscan_bottom;
-+ params.ucOverscanTop = (uint8_t)bp_params->v_overscan_top;
-+
-+ if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
-+ params.susModeMiscInfo.usAccess =
-+ cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
-+
-+ if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
-+ params.susModeMiscInfo.usAccess =
-+ cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
-+
-+ if (bp_params->flags.INTERLACE) {
-+ params.susModeMiscInfo.usAccess =
-+ cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
-+
-+ /* original DAL code has this condition to apply tis for
-+ * non-TV/CV only due to complex MV testing for possible
-+ * impact
-+ * if (pACParameters->signal != SignalType_YPbPr &&
-+ * pACParameters->signal != SignalType_Composite &&
-+ * pACParameters->signal != SignalType_SVideo)
-+ */
-+ /* HW will deduct 0.5 line from 2nd feild.
-+ * i.e. for 1080i, it is 2 lines for 1st field, 2.5
-+ * lines for the 2nd feild. we need input as 5 instead
-+ * of 4, but it is 4 either from Edid data
-+ * (spec CEA 861) or CEA timing table.
-+ */
-+ params.usV_SyncStart =
-+ cpu_to_le16((uint16_t)(bp_params->v_sync_start + 1));
-+ }
-+
-+ if (bp_params->flags.HORZ_COUNT_BY_TWO)
-+ params.susModeMiscInfo.usAccess =
-+ cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
-+
-+ if (EXEC_BIOS_CMD_TABLE(SetCRTC_Timing, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+static enum bp_result set_crtc_using_dtd_timing_v3(
-+ struct bios_parser *bp,
-+ struct bp_hw_crtc_timing_parameters *bp_params)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ SET_CRTC_USING_DTD_TIMING_PARAMETERS params = {0};
-+ uint8_t atom_controller_id;
-+
-+ if (bp->cmd_helper->controller_id_to_atom(
-+ bp_params->controller_id, &atom_controller_id))
-+ params.ucCRTC = atom_controller_id;
-+
-+ /* bios usH_Size wants h addressable size */
-+ params.usH_Size = cpu_to_le16((uint16_t)bp_params->h_addressable);
-+ /* bios usH_Blanking_Time wants borders included in blanking */
-+ params.usH_Blanking_Time =
-+ cpu_to_le16((uint16_t)(bp_params->h_total - bp_params->h_addressable));
-+ /* bios usV_Size wants v addressable size */
-+ params.usV_Size = cpu_to_le16((uint16_t)bp_params->v_addressable);
-+ /* bios usV_Blanking_Time wants borders included in blanking */
-+ params.usV_Blanking_Time =
-+ cpu_to_le16((uint16_t)(bp_params->v_total - bp_params->v_addressable));
-+ /* bios usHSyncOffset is the offset from the end of h addressable,
-+ * our horizontalSyncStart is the offset from the beginning
-+ * of h addressable */
-+ params.usH_SyncOffset =
-+ cpu_to_le16((uint16_t)(bp_params->h_sync_start - bp_params->h_addressable));
-+ params.usH_SyncWidth = cpu_to_le16((uint16_t)bp_params->h_sync_width);
-+ /* bios usHSyncOffset is the offset from the end of v addressable,
-+ * our verticalSyncStart is the offset from the beginning of
-+ * v addressable */
-+ params.usV_SyncOffset =
-+ cpu_to_le16((uint16_t)(bp_params->v_sync_start - bp_params->v_addressable));
-+ params.usV_SyncWidth = cpu_to_le16((uint16_t)bp_params->v_sync_width);
-+
-+ /* we assume that overscan from original timing does not get bigger
-+ * than 255
-+ * we will program all the borders in the Set CRTC Overscan call below
-+ */
-+
-+ if (0 == bp_params->flags.HSYNC_POSITIVE_POLARITY)
-+ params.susModeMiscInfo.usAccess =
-+ cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_HSYNC_POLARITY);
-+
-+ if (0 == bp_params->flags.VSYNC_POSITIVE_POLARITY)
-+ params.susModeMiscInfo.usAccess =
-+ cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_VSYNC_POLARITY);
-+
-+
-+ if (bp_params->flags.INTERLACE) {
-+ params.susModeMiscInfo.usAccess =
-+ cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_INTERLACE);
-+
-+ /* original DAL code has this condition to apply this
-+ * for non-TV/CV only
-+ * due to complex MV testing for possible impact
-+ * if ( pACParameters->signal != SignalType_YPbPr &&
-+ * pACParameters->signal != SignalType_Composite &&
-+ * pACParameters->signal != SignalType_SVideo)
-+ */
-+ {
-+ /* HW will deduct 0.5 line from 2nd feild.
-+ * i.e. for 1080i, it is 2 lines for 1st field,
-+ * 2.5 lines for the 2nd feild. we need input as 5
-+ * instead of 4.
-+ * but it is 4 either from Edid data (spec CEA 861)
-+ * or CEA timing table.
-+ */
-+ params.usV_SyncOffset =
-+ cpu_to_le16(le16_to_cpu(params.usV_SyncOffset) + 1);
-+
-+ }
-+ }
-+
-+ if (bp_params->flags.HORZ_COUNT_BY_TWO)
-+ params.susModeMiscInfo.usAccess =
-+ cpu_to_le16(le16_to_cpu(params.susModeMiscInfo.usAccess) | ATOM_DOUBLE_CLOCK_MODE);
-+
-+ if (EXEC_BIOS_CMD_TABLE(SetCRTC_UsingDTDTiming, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** SET CRTC OVERSCAN
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result set_crtc_overscan_v1(
-+ struct bios_parser *bp,
-+ struct bp_hw_crtc_overscan_parameters *bp_params);
-+
-+static void init_set_crtc_overscan(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(SetCRTC_OverScan)) {
-+ case 1:
-+ bp->cmd_tbl.set_crtc_overscan = set_crtc_overscan_v1;
-+ break;
-+ default:
-+ bp->cmd_tbl.set_crtc_overscan = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result set_crtc_overscan_v1(
-+ struct bios_parser *bp,
-+ struct bp_hw_crtc_overscan_parameters *bp_params)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ SET_CRTC_OVERSCAN_PARAMETERS params = {0};
-+ uint8_t atom_controller_id;
-+
-+ if (bp->cmd_helper->controller_id_to_atom(
-+ bp_params->controller_id, &atom_controller_id))
-+ params.ucCRTC = atom_controller_id;
-+ else
-+ return BP_RESULT_BADINPUT;
-+
-+ params.usOverscanRight =
-+ cpu_to_le16((uint16_t)bp_params->h_overscan_right);
-+ params.usOverscanLeft =
-+ cpu_to_le16((uint16_t)bp_params->h_overscan_left);
-+ params.usOverscanBottom =
-+ cpu_to_le16((uint16_t)bp_params->v_overscan_bottom);
-+ params.usOverscanTop =
-+ cpu_to_le16((uint16_t)bp_params->v_overscan_top);
-+
-+ if (EXEC_BIOS_CMD_TABLE(SetCRTC_OverScan, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** SELECT CRTC SOURCE
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result select_crtc_source_v2(
-+ struct bios_parser *bp,
-+ struct bp_crtc_source_select *bp_params);
-+static enum bp_result select_crtc_source_v3(
-+ struct bios_parser *bp,
-+ struct bp_crtc_source_select *bp_params);
-+
-+static void init_select_crtc_source(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(SelectCRTC_Source)) {
-+ case 2:
-+ bp->cmd_tbl.select_crtc_source = select_crtc_source_v2;
-+ break;
-+ case 3:
-+ bp->cmd_tbl.select_crtc_source = select_crtc_source_v3;
-+ break;
-+ default:
-+ bp->cmd_tbl.select_crtc_source = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result select_crtc_source_v2(
-+ struct bios_parser *bp,
-+ struct bp_crtc_source_select *bp_params)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ SELECT_CRTC_SOURCE_PARAMETERS_V2 params;
-+ uint8_t atom_controller_id;
-+ uint32_t atom_engine_id;
-+ enum signal_type s = bp_params->signal;
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+
-+ /* set controller id */
-+ if (bp->cmd_helper->controller_id_to_atom(
-+ bp_params->controller_id, &atom_controller_id))
-+ params.ucCRTC = atom_controller_id;
-+ else
-+ return BP_RESULT_FAILURE;
-+
-+ /* set encoder id */
-+ if (bp->cmd_helper->engine_bp_to_atom(
-+ bp_params->engine_id, &atom_engine_id))
-+ params.ucEncoderID = (uint8_t)atom_engine_id;
-+ else
-+ return BP_RESULT_FAILURE;
-+
-+ if (SIGNAL_TYPE_EDP == s ||
-+ (SIGNAL_TYPE_DISPLAY_PORT == s &&
-+ SIGNAL_TYPE_LVDS == bp_params->sink_signal))
-+ s = SIGNAL_TYPE_LVDS;
-+
-+ params.ucEncodeMode =
-+ (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
-+ s, bp_params->enable_dp_audio);
-+
-+ if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+static enum bp_result select_crtc_source_v3(
-+ struct bios_parser *bp,
-+ struct bp_crtc_source_select *bp_params)
-+{
-+ bool result = BP_RESULT_FAILURE;
-+ SELECT_CRTC_SOURCE_PARAMETERS_V3 params;
-+ uint8_t atom_controller_id;
-+ uint32_t atom_engine_id;
-+ enum signal_type s = bp_params->signal;
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+
-+ if (bp->cmd_helper->controller_id_to_atom(bp_params->controller_id,
-+ &atom_controller_id))
-+ params.ucCRTC = atom_controller_id;
-+ else
-+ return result;
-+
-+ if (bp->cmd_helper->engine_bp_to_atom(bp_params->engine_id,
-+ &atom_engine_id))
-+ params.ucEncoderID = (uint8_t)atom_engine_id;
-+ else
-+ return result;
-+
-+ if (SIGNAL_TYPE_EDP == s ||
-+ (SIGNAL_TYPE_DISPLAY_PORT == s &&
-+ SIGNAL_TYPE_LVDS == bp_params->sink_signal))
-+ s = SIGNAL_TYPE_LVDS;
-+
-+ params.ucEncodeMode =
-+ bp->cmd_helper->encoder_mode_bp_to_atom(
-+ s, bp_params->enable_dp_audio);
-+ /* Needed for VBIOS Random Spatial Dithering feature */
-+ params.ucDstBpc = (uint8_t)(bp_params->display_output_bit_depth);
-+
-+ if (EXEC_BIOS_CMD_TABLE(SelectCRTC_Source, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** ENABLE CRTC
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result enable_crtc_v1(
-+ struct bios_parser *bp,
-+ enum controller_id controller_id,
-+ bool enable);
-+
-+static void init_enable_crtc(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTC)) {
-+ case 1:
-+ bp->cmd_tbl.enable_crtc = enable_crtc_v1;
-+ break;
-+ default:
-+ bp->cmd_tbl.enable_crtc = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result enable_crtc_v1(
-+ struct bios_parser *bp,
-+ enum controller_id controller_id,
-+ bool enable)
-+{
-+ bool result = BP_RESULT_FAILURE;
-+ ENABLE_CRTC_PARAMETERS params = {0};
-+ uint8_t id;
-+
-+ if (bp->cmd_helper->controller_id_to_atom(controller_id, &id))
-+ params.ucCRTC = id;
-+ else
-+ return BP_RESULT_BADINPUT;
-+
-+ if (enable)
-+ params.ucEnable = ATOM_ENABLE;
-+ else
-+ params.ucEnable = ATOM_DISABLE;
-+
-+ if (EXEC_BIOS_CMD_TABLE(EnableCRTC, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** ENABLE CRTC MEM REQ
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result enable_crtc_mem_req_v1(
-+ struct bios_parser *bp,
-+ enum controller_id controller_id,
-+ bool enable);
-+
-+static void init_enable_crtc_mem_req(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(EnableCRTCMemReq)) {
-+ case 1:
-+ bp->cmd_tbl.enable_crtc_mem_req = enable_crtc_mem_req_v1;
-+ break;
-+ default:
-+ bp->cmd_tbl.enable_crtc_mem_req = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result enable_crtc_mem_req_v1(
-+ struct bios_parser *bp,
-+ enum controller_id controller_id,
-+ bool enable)
-+{
-+ bool result = BP_RESULT_BADINPUT;
-+ ENABLE_CRTC_PARAMETERS params = {0};
-+ uint8_t id;
-+
-+ if (bp->cmd_helper->controller_id_to_atom(controller_id, &id)) {
-+ params.ucCRTC = id;
-+
-+ if (enable)
-+ params.ucEnable = ATOM_ENABLE;
-+ else
-+ params.ucEnable = ATOM_DISABLE;
-+
-+ if (EXEC_BIOS_CMD_TABLE(EnableCRTCMemReq, params))
-+ result = BP_RESULT_OK;
-+ else
-+ result = BP_RESULT_FAILURE;
-+ }
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** DISPLAY PLL
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result program_clock_v5(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params);
-+static enum bp_result program_clock_v6(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params);
-+
-+static void init_program_clock(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(SetPixelClock)) {
-+ case 5:
-+ bp->cmd_tbl.program_clock = program_clock_v5;
-+ break;
-+ case 6:
-+ bp->cmd_tbl.program_clock = program_clock_v6;
-+ break;
-+ default:
-+ bp->cmd_tbl.program_clock = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result program_clock_v5(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+
-+ SET_PIXEL_CLOCK_PS_ALLOCATION_V5 params;
-+ uint32_t atom_pll_id;
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+ if (!bp->cmd_helper->clock_source_id_to_atom(
-+ bp_params->pll_id, &atom_pll_id)) {
-+ BREAK_TO_DEBUGGER(); /* Invalid Inpute!! */
-+ return BP_RESULT_BADINPUT;
-+ }
-+
-+ /* We need to convert from KHz units into 10KHz units */
-+ params.sPCLKInput.ucPpll = (uint8_t) atom_pll_id;
-+ params.sPCLKInput.usPixelClock =
-+ cpu_to_le16((uint16_t) (bp_params->target_pixel_clock / 10));
-+ params.sPCLKInput.ucCRTC = (uint8_t) ATOM_CRTC_INVALID;
-+
-+ if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
-+ params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
-+
-+ if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+
-+static enum bp_result program_clock_v6(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+
-+ SET_PIXEL_CLOCK_PS_ALLOCATION_V6 params;
-+ uint32_t atom_pll_id;
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+
-+ if (!bp->cmd_helper->clock_source_id_to_atom(
-+ bp_params->pll_id, &atom_pll_id)) {
-+ BREAK_TO_DEBUGGER(); /*Invalid Input!!*/
-+ return BP_RESULT_BADINPUT;
-+ }
-+
-+ /* We need to convert from KHz units into 10KHz units */
-+ params.sPCLKInput.ucPpll = (uint8_t)atom_pll_id;
-+ params.sPCLKInput.ulDispEngClkFreq =
-+ cpu_to_le32(bp_params->target_pixel_clock / 10);
-+
-+ if (bp_params->flags.SET_EXTERNAL_REF_DIV_SRC)
-+ params.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
-+
-+ if (EXEC_BIOS_CMD_TABLE(SetPixelClock, params)) {
-+ /* True display clock is returned by VBIOS if DFS bypass
-+ * is enabled. */
-+ bp_params->dfs_bypass_display_clock =
-+ (uint32_t)(le32_to_cpu(params.sPCLKInput.ulDispEngClkFreq) * 10);
-+ result = BP_RESULT_OK;
-+ }
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** COMPUTE MEMORY ENGINE PLL
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result compute_memore_engine_pll_v4(
-+ struct bios_parser *bp,
-+ struct bp_display_clock_parameters *bp_params);
-+
-+static void init_compute_memore_engine_pll(struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(ComputeMemoryEnginePLL)) {
-+ case 4:
-+ bp->cmd_tbl.compute_memore_engine_pll =
-+ compute_memore_engine_pll_v4;
-+ break;
-+ default:
-+ bp->cmd_tbl.compute_memore_engine_pll = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result compute_memore_engine_pll_v4(
-+ struct bios_parser *bp,
-+ struct bp_display_clock_parameters *bp_params)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 params;
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+
-+ params.ulClock = cpu_to_le32(bp_params->target_display_clock / 10);
-+
-+ /* Initialize this to the target clock in case this call fails */
-+ bp_params->actual_display_clock = bp_params->target_display_clock;
-+
-+ if (EXEC_BIOS_CMD_TABLE(ComputeMemoryEnginePLL, params)) {
-+ /* Convert from 10KHz units back to KHz */
-+ bp_params->actual_display_clock =
-+ le32_to_cpu(params.ulClock) * 10;
-+ bp_params->actual_post_divider_id = params.ucPostDiv;
-+ result = BP_RESULT_OK;
-+ }
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** EXTERNAL ENCODER CONTROL
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result external_encoder_control_v3(
-+ struct bios_parser *bp,
-+ struct bp_external_encoder_control *cntl);
-+
-+static void init_external_encoder_control(
-+ struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(ExternalEncoderControl)) {
-+ case 3:
-+ bp->cmd_tbl.external_encoder_control =
-+ external_encoder_control_v3;
-+ break;
-+ default:
-+ bp->cmd_tbl.external_encoder_control = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result external_encoder_control_v3(
-+ struct bios_parser *bp,
-+ struct bp_external_encoder_control *cntl)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+
-+ /* we need use _PS_Alloc struct */
-+ EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 params;
-+ EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 *cntl_params;
-+ struct graphics_object_id encoder;
-+ bool is_input_signal_dp = false;
-+
-+ dc_service_memset(&params, 0, sizeof(params));
-+
-+ cntl_params = &params.sExtEncoder;
-+
-+ encoder = cntl->encoder_id;
-+
-+ /* check if encoder supports external encoder control table */
-+ switch (dal_graphics_object_id_get_encoder_id(encoder)) {
-+ case ENCODER_ID_EXTERNAL_NUTMEG:
-+ case ENCODER_ID_EXTERNAL_TRAVIS:
-+ is_input_signal_dp = true;
-+ break;
-+
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ return BP_RESULT_BADINPUT;
-+ }
-+
-+ /* Fill information based on the action
-+ *
-+ * Bit[6:4]: indicate external encoder, applied to all functions.
-+ * =0: external encoder1, mapped to external encoder enum id1
-+ * =1: external encoder2, mapped to external encoder enum id2
-+ *
-+ * enum ObjectEnumId
-+ * {
-+ * EnumId_Unknown = 0,
-+ * EnumId_1,
-+ * EnumId_2,
-+ * };
-+ */
-+ cntl_params->ucConfig = (uint8_t)((encoder.enum_id - 1) << 4);
-+
-+ switch (cntl->action) {
-+ case EXTERNAL_ENCODER_CONTROL_INIT:
-+ /* output display connector type. Only valid in encoder
-+ * initialization */
-+ cntl_params->usConnectorId =
-+ cpu_to_le16((uint16_t)cntl->connector_obj_id.id);
-+ break;
-+ case EXTERNAL_ENCODER_CONTROL_SETUP:
-+ /* EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 pixel clock unit in
-+ * 10KHz
-+ * output display device pixel clock frequency in unit of 10KHz.
-+ * Only valid in setup and enableoutput
-+ */
-+ cntl_params->usPixelClock =
-+ cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
-+ /* Indicate display output signal type drive by external
-+ * encoder, only valid in setup and enableoutput */
-+ cntl_params->ucEncoderMode =
-+ (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
-+ cntl->signal, false);
-+
-+ if (is_input_signal_dp) {
-+ /* Bit[0]: indicate link rate, =1: 2.7Ghz, =0: 1.62Ghz,
-+ * only valid in encoder setup with DP mode. */
-+ if (LINK_RATE_HIGH == cntl->link_rate)
-+ cntl_params->ucConfig |= 1;
-+ /* output color depth Indicate encoder data bpc format
-+ * in DP mode, only valid in encoder setup in DP mode.
-+ */
-+ cntl_params->ucBitPerColor =
-+ (uint8_t)(cntl->color_depth);
-+ }
-+ /* Indicate how many lanes used by external encoder, only valid
-+ * in encoder setup and enableoutput. */
-+ cntl_params->ucLaneNum = (uint8_t)(cntl->lanes_number);
-+ break;
-+ case EXTERNAL_ENCODER_CONTROL_ENABLE:
-+ cntl_params->usPixelClock =
-+ cpu_to_le16((uint16_t)(cntl->pixel_clock / 10));
-+ cntl_params->ucEncoderMode =
-+ (uint8_t)bp->cmd_helper->encoder_mode_bp_to_atom(
-+ cntl->signal, false);
-+ cntl_params->ucLaneNum = (uint8_t)cntl->lanes_number;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ cntl_params->ucAction = (uint8_t)cntl->action;
-+
-+ if (EXEC_BIOS_CMD_TABLE(ExternalEncoderControl, params))
-+ result = BP_RESULT_OK;
-+
-+ if (EXTERNAL_ENCODER_CONTROL_DAC_LOAD_DETECT == cntl->action) {
-+#if defined(CONFIG_DRM_AMD_DAL_VBIOS_PRESENT)
-+ if (BP_RESULT_OK == result)
-+ /* get VBIOS result from scratch register.
-+ * ExternalEncoderControl runs detection and save result
-+ * in BIOS scratch registers. */
-+ cntl->signal = bp->bios_helper->detect_sink(
-+ bp->ctx,
-+ encoder,
-+ cntl->connector_obj_id,
-+ cntl->signal);
-+ else/* BIOS table does not work. */
-+#endif
-+ {
-+ BREAK_TO_DEBUGGER(); /* VBios is needed */
-+ cntl->signal = SIGNAL_TYPE_NONE;
-+ }
-+ }
-+
-+ return result;
-+}
-+
-+/*******************************************************************************
-+********************************************************************************
-+**
-+** ENABLE DISPLAY POWER GATING
-+**
-+********************************************************************************
-+*******************************************************************************/
-+
-+static enum bp_result enable_disp_power_gating_v2_1(
-+ struct bios_parser *bp,
-+ enum controller_id crtc_id,
-+ enum bp_pipe_control_action action);
-+
-+static void init_enable_disp_power_gating(
-+ struct bios_parser *bp)
-+{
-+ switch (BIOS_CMD_TABLE_PARA_REVISION(EnableDispPowerGating)) {
-+ case 1:
-+ bp->cmd_tbl.enable_disp_power_gating =
-+ enable_disp_power_gating_v2_1;
-+ break;
-+ default:
-+ bp->cmd_tbl.enable_disp_power_gating = NULL;
-+ break;
-+ }
-+}
-+
-+static enum bp_result enable_disp_power_gating_v2_1(
-+ struct bios_parser *bp,
-+ enum controller_id crtc_id,
-+ enum bp_pipe_control_action action)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+
-+ ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 params = {0};
-+ uint8_t atom_crtc_id;
-+
-+ if (bp->cmd_helper->controller_id_to_atom(crtc_id, &atom_crtc_id))
-+ params.ucDispPipeId = atom_crtc_id;
-+ else
-+ return BP_RESULT_BADINPUT;
-+
-+ params.ucEnable =
-+ bp->cmd_helper->disp_power_gating_action_to_atom(action);
-+
-+ if (EXEC_BIOS_CMD_TABLE(EnableDispPowerGating, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/command_table.h b/drivers/gpu/drm/amd/dal/dc/bios/command_table.h
-new file mode 100644
-index 0000000..814d31f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/command_table.h
-@@ -0,0 +1,117 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_COMMAND_TABLE_H__
-+#define __DAL_COMMAND_TABLE_H__
-+
-+struct bios_parser;
-+struct bp_encoder_control;
-+
-+struct cmd_tbl {
-+ enum bp_result (*dig_encoder_control)(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *control);
-+ enum bp_result (*encoder_control_dig1)(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *control);
-+ enum bp_result (*encoder_control_dig2)(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *control);
-+ enum bp_result (*dvo_encoder_control)(
-+ struct bios_parser *bp,
-+ struct bp_dvo_encoder_control *cntl);
-+ enum bp_result (*transmitter_control)(
-+ struct bios_parser *bp,
-+ struct bp_transmitter_control *control);
-+ enum bp_result (*set_pixel_clock)(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params);
-+ enum bp_result (*enable_spread_spectrum_on_ppll)(
-+ struct bios_parser *bp,
-+ struct bp_spread_spectrum_parameters *bp_params,
-+ bool enable);
-+ enum bp_result (*adjust_display_pll)(
-+ struct bios_parser *bp,
-+ struct bp_adjust_pixel_clock_parameters *bp_params);
-+ enum bp_result (*dac1_encoder_control)(
-+ struct bios_parser *bp,
-+ bool enable,
-+ uint32_t pixel_clock,
-+ uint8_t dac_standard);
-+ enum bp_result (*dac2_encoder_control)(
-+ struct bios_parser *bp,
-+ bool enable,
-+ uint32_t pixel_clock,
-+ uint8_t dac_standard);
-+ enum bp_result (*dac1_output_control)(
-+ struct bios_parser *bp,
-+ bool enable);
-+ enum bp_result (*dac2_output_control)(
-+ struct bios_parser *bp,
-+ bool enable);
-+ enum signal_type (*dac_load_detection)(
-+ struct bios_parser *bp,
-+ struct graphics_object_id encoder,
-+ struct graphics_object_id connector,
-+ enum signal_type display_signal);
-+ enum bp_result (*blank_crtc)(
-+ struct bios_parser *bp,
-+ struct bp_blank_crtc_parameters *bp_params,
-+ bool blank);
-+ enum bp_result (*set_crtc_timing)(
-+ struct bios_parser *bp,
-+ struct bp_hw_crtc_timing_parameters *bp_params);
-+ enum bp_result (*set_crtc_overscan)(
-+ struct bios_parser *bp,
-+ struct bp_hw_crtc_overscan_parameters *bp_params);
-+ enum bp_result (*select_crtc_source)(
-+ struct bios_parser *bp,
-+ struct bp_crtc_source_select *bp_params);
-+ enum bp_result (*enable_crtc)(
-+ struct bios_parser *bp,
-+ enum controller_id controller_id,
-+ bool enable);
-+ enum bp_result (*enable_crtc_mem_req)(
-+ struct bios_parser *bp,
-+ enum controller_id controller_id,
-+ bool enable);
-+ enum bp_result (*program_clock)(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params);
-+ enum bp_result (*compute_memore_engine_pll)(
-+ struct bios_parser *bp,
-+ struct bp_display_clock_parameters *bp_params);
-+ enum bp_result (*external_encoder_control)(
-+ struct bios_parser *bp,
-+ struct bp_external_encoder_control *cntl);
-+ enum bp_result (*enable_disp_power_gating)(
-+ struct bios_parser *bp,
-+ enum controller_id crtc_id,
-+ enum bp_pipe_control_action action);
-+};
-+
-+void dal_bios_parser_init_cmd_tbl(struct bios_parser *bp);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/command_table_helper.c b/drivers/gpu/drm/amd/dal/dc/bios/command_table_helper.c
-new file mode 100644
-index 0000000..dad1426
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/command_table_helper.c
-@@ -0,0 +1,315 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "atom.h"
-+
-+#include "include/bios_parser_types.h"
-+#include "include/adapter_service_types.h"
-+
-+#include "command_table_helper.h"
-+
-+bool dal_bios_parser_init_cmd_tbl_helper(
-+ const struct command_table_helper **h,
-+ enum dce_version dce)
-+{
-+ switch (dce) {
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ case DCE_VERSION_11_0:
-+ *h = dal_cmd_tbl_helper_dce110_get_table();
-+ return true;
-+
-+#endif
-+ default:
-+ /* Unsupported DCE */
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+}
-+
-+/* real implementations */
-+
-+bool dal_cmd_table_helper_controller_id_to_atom(
-+ enum controller_id id,
-+ uint8_t *atom_id)
-+{
-+ if (atom_id == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ switch (id) {
-+ case CONTROLLER_ID_D0:
-+ *atom_id = ATOM_CRTC1;
-+ return true;
-+ case CONTROLLER_ID_D1:
-+ *atom_id = ATOM_CRTC2;
-+ return true;
-+ case CONTROLLER_ID_D2:
-+ *atom_id = ATOM_CRTC3;
-+ return true;
-+ case CONTROLLER_ID_D3:
-+ *atom_id = ATOM_CRTC4;
-+ return true;
-+ case CONTROLLER_ID_D4:
-+ *atom_id = ATOM_CRTC5;
-+ return true;
-+ case CONTROLLER_ID_D5:
-+ *atom_id = ATOM_CRTC6;
-+ return true;
-+ case CONTROLLER_ID_UNDERLAY0:
-+ *atom_id = ATOM_UNDERLAY_PIPE0;
-+ return true;
-+ case CONTROLLER_ID_UNDEFINED:
-+ *atom_id = ATOM_CRTC_INVALID;
-+ return true;
-+ default:
-+ /* Wrong controller id */
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+}
-+
-+/**
-+* translate_transmitter_bp_to_atom
-+*
-+* @brief
-+* Translate the Transmitter to the corresponding ATOM BIOS value
-+*
-+* @param
-+* input transmitter
-+* output digitalTransmitter
-+* // =00: Digital Transmitter1 ( UNIPHY linkAB )
-+* // =01: Digital Transmitter2 ( UNIPHY linkCD )
-+* // =02: Digital Transmitter3 ( UNIPHY linkEF )
-+*/
-+uint8_t dal_cmd_table_helper_transmitter_bp_to_atom(
-+ enum transmitter t)
-+{
-+ switch (t) {
-+ case TRANSMITTER_UNIPHY_A:
-+ case TRANSMITTER_UNIPHY_B:
-+ case TRANSMITTER_TRAVIS_LCD:
-+ return 0;
-+ case TRANSMITTER_UNIPHY_C:
-+ case TRANSMITTER_UNIPHY_D:
-+ return 1;
-+ case TRANSMITTER_UNIPHY_E:
-+ case TRANSMITTER_UNIPHY_F:
-+ return 2;
-+ default:
-+ /* Invalid Transmitter Type! */
-+ BREAK_TO_DEBUGGER();
-+ return 0;
-+ }
-+}
-+
-+uint32_t dal_cmd_table_helper_encoder_mode_bp_to_atom(
-+ enum signal_type s,
-+ bool enable_dp_audio)
-+{
-+ switch (s) {
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
-+ case SIGNAL_TYPE_DVI_DUAL_LINK:
-+ return ATOM_ENCODER_MODE_DVI;
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ return ATOM_ENCODER_MODE_HDMI;
-+ case SIGNAL_TYPE_LVDS:
-+ return ATOM_ENCODER_MODE_LVDS;
-+ case SIGNAL_TYPE_EDP:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ if (enable_dp_audio)
-+ return ATOM_ENCODER_MODE_DP_AUDIO;
-+ else
-+ return ATOM_ENCODER_MODE_DP;
-+ case SIGNAL_TYPE_RGB:
-+ return ATOM_ENCODER_MODE_CRT;
-+ default:
-+ return ATOM_ENCODER_MODE_CRT;
-+ }
-+}
-+
-+void dal_cmd_table_helper_assign_control_parameter(
-+ const struct command_table_helper *h,
-+ struct bp_encoder_control *control,
-+ DIG_ENCODER_CONTROL_PARAMETERS_V2 *ctrl_param)
-+{
-+ /* there are three transmitter blocks, each one has two links 4-lanes
-+ * each, A+B, C+D, E+F, Uniphy A, C and E are enumerated as link 0 in
-+ * each transmitter block B, D and F as link 1, third transmitter block
-+ * has non splitable links (UniphyE and UniphyF can not be configured
-+ * separately to drive two different streams)
-+ */
-+ if ((control->transmitter == TRANSMITTER_UNIPHY_B) ||
-+ (control->transmitter == TRANSMITTER_UNIPHY_D) ||
-+ (control->transmitter == TRANSMITTER_UNIPHY_F)) {
-+ /* Bit2: Link Select
-+ * =0: PHY linkA/C/E
-+ * =1: PHY linkB/D/F
-+ */
-+ ctrl_param->acConfig.ucLinkSel = 1;
-+ }
-+
-+ /* Bit[4:3]: Transmitter Selection
-+ * =00: Digital Transmitter1 ( UNIPHY linkAB )
-+ * =01: Digital Transmitter2 ( UNIPHY linkCD )
-+ * =02: Digital Transmitter3 ( UNIPHY linkEF )
-+ * =03: Reserved
-+ */
-+ ctrl_param->acConfig.ucTransmitterSel =
-+ (uint8_t)(h->transmitter_bp_to_atom(control->transmitter));
-+
-+ /* We need to convert from KHz units into 10KHz units */
-+ ctrl_param->ucAction = h->encoder_action_to_atom(control->action);
-+ ctrl_param->usPixelClock = cpu_to_le16((uint16_t)(control->pixel_clock / 10));
-+ ctrl_param->ucEncoderMode =
-+ (uint8_t)(h->encoder_mode_bp_to_atom(
-+ control->signal, control->enable_dp_audio));
-+ ctrl_param->ucLaneNum = (uint8_t)(control->lanes_number);
-+}
-+
-+bool dal_cmd_table_helper_clock_source_id_to_ref_clk_src(
-+ enum clock_source_id id,
-+ uint32_t *ref_clk_src_id)
-+{
-+ if (ref_clk_src_id == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ switch (id) {
-+ case CLOCK_SOURCE_ID_PLL1:
-+ *ref_clk_src_id = ENCODER_REFCLK_SRC_P1PLL;
-+ return true;
-+ case CLOCK_SOURCE_ID_PLL2:
-+ *ref_clk_src_id = ENCODER_REFCLK_SRC_P2PLL;
-+ return true;
-+ case CLOCK_SOURCE_ID_DCPLL:
-+ *ref_clk_src_id = ENCODER_REFCLK_SRC_DCPLL;
-+ return true;
-+ case CLOCK_SOURCE_ID_EXTERNAL:
-+ *ref_clk_src_id = ENCODER_REFCLK_SRC_EXTCLK;
-+ return true;
-+ case CLOCK_SOURCE_ID_UNDEFINED:
-+ *ref_clk_src_id = ENCODER_REFCLK_SRC_INVALID;
-+ return true;
-+ default:
-+ /* Unsupported clock source id */
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+}
-+
-+uint8_t dal_cmd_table_helper_encoder_id_to_atom(
-+ enum encoder_id id)
-+{
-+ switch (id) {
-+ case ENCODER_ID_INTERNAL_LVDS:
-+ return ENCODER_OBJECT_ID_INTERNAL_LVDS;
-+ case ENCODER_ID_INTERNAL_TMDS1:
-+ return ENCODER_OBJECT_ID_INTERNAL_TMDS1;
-+ case ENCODER_ID_INTERNAL_TMDS2:
-+ return ENCODER_OBJECT_ID_INTERNAL_TMDS2;
-+ case ENCODER_ID_INTERNAL_DAC1:
-+ return ENCODER_OBJECT_ID_INTERNAL_DAC1;
-+ case ENCODER_ID_INTERNAL_DAC2:
-+ return ENCODER_OBJECT_ID_INTERNAL_DAC2;
-+ case ENCODER_ID_INTERNAL_SDVOA:
-+ return ENCODER_OBJECT_ID_INTERNAL_SDVOA;
-+ case ENCODER_ID_INTERNAL_SDVOB:
-+ return ENCODER_OBJECT_ID_INTERNAL_SDVOB;
-+ case ENCODER_ID_EXTERNAL_SI170B:
-+ return ENCODER_OBJECT_ID_SI170B;
-+ case ENCODER_ID_EXTERNAL_CH7303:
-+ return ENCODER_OBJECT_ID_CH7303;
-+ case ENCODER_ID_EXTERNAL_CH7301:
-+ return ENCODER_OBJECT_ID_CH7301;
-+ case ENCODER_ID_INTERNAL_DVO1:
-+ return ENCODER_OBJECT_ID_INTERNAL_DVO1;
-+ case ENCODER_ID_EXTERNAL_SDVOA:
-+ return ENCODER_OBJECT_ID_EXTERNAL_SDVOA;
-+ case ENCODER_ID_EXTERNAL_SDVOB:
-+ return ENCODER_OBJECT_ID_EXTERNAL_SDVOB;
-+ case ENCODER_ID_EXTERNAL_TITFP513:
-+ return ENCODER_OBJECT_ID_TITFP513;
-+ case ENCODER_ID_INTERNAL_LVTM1:
-+ return ENCODER_OBJECT_ID_INTERNAL_LVTM1;
-+ case ENCODER_ID_EXTERNAL_VT1623:
-+ return ENCODER_OBJECT_ID_VT1623;
-+ case ENCODER_ID_EXTERNAL_SI1930:
-+ return ENCODER_OBJECT_ID_HDMI_SI1930;
-+ case ENCODER_ID_INTERNAL_HDMI:
-+ return ENCODER_OBJECT_ID_HDMI_INTERNAL;
-+ case ENCODER_ID_EXTERNAL_TRAVIS:
-+ return ENCODER_OBJECT_ID_TRAVIS;
-+ case ENCODER_ID_EXTERNAL_NUTMEG:
-+ return ENCODER_OBJECT_ID_NUTMEG;
-+ case ENCODER_ID_INTERNAL_KLDSCP_TMDS1:
-+ return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1;
-+ case ENCODER_ID_INTERNAL_KLDSCP_DVO1:
-+ return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
-+ case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
-+ return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
-+ case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
-+ return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
-+ case ENCODER_ID_EXTERNAL_SI178:
-+ return ENCODER_OBJECT_ID_SI178;
-+ case ENCODER_ID_EXTERNAL_MVPU_FPGA:
-+ return ENCODER_OBJECT_ID_MVPU_FPGA;
-+ case ENCODER_ID_INTERNAL_DDI:
-+ return ENCODER_OBJECT_ID_INTERNAL_DDI;
-+ case ENCODER_ID_EXTERNAL_VT1625:
-+ return ENCODER_OBJECT_ID_VT1625;
-+ case ENCODER_ID_EXTERNAL_SI1932:
-+ return ENCODER_OBJECT_ID_HDMI_SI1932;
-+ case ENCODER_ID_EXTERNAL_AN9801:
-+ return ENCODER_OBJECT_ID_DP_AN9801;
-+ case ENCODER_ID_EXTERNAL_DP501:
-+ return ENCODER_OBJECT_ID_DP_DP501;
-+ case ENCODER_ID_INTERNAL_UNIPHY:
-+ return ENCODER_OBJECT_ID_INTERNAL_UNIPHY;
-+ case ENCODER_ID_INTERNAL_KLDSCP_LVTMA:
-+ return ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
-+ case ENCODER_ID_INTERNAL_UNIPHY1:
-+ return ENCODER_OBJECT_ID_INTERNAL_UNIPHY1;
-+ case ENCODER_ID_INTERNAL_UNIPHY2:
-+ return ENCODER_OBJECT_ID_INTERNAL_UNIPHY2;
-+ case ENCODER_ID_INTERNAL_UNIPHY3:
-+ return ENCODER_OBJECT_ID_INTERNAL_UNIPHY3;
-+ case ENCODER_ID_INTERNAL_WIRELESS:
-+ return ENCODER_OBJECT_ID_INTERNAL_VCE;
-+ case ENCODER_ID_EXTERNAL_GENERIC_DVO:
-+ return ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO;
-+ case ENCODER_ID_UNKNOWN:
-+ return ENCODER_OBJECT_ID_NONE;
-+ default:
-+ /* Invalid encoder id */
-+ BREAK_TO_DEBUGGER();
-+ return ENCODER_OBJECT_ID_NONE;
-+ }
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/command_table_helper.h b/drivers/gpu/drm/amd/dal/dc/bios/command_table_helper.h
-new file mode 100644
-index 0000000..e5c00de
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/command_table_helper.h
-@@ -0,0 +1,87 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_COMMAND_TABLE_HELPER_H__
-+#define __DAL_COMMAND_TABLE_HELPER_H__
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+#include "dce110/command_table_helper_dce110.h"
-+#endif
-+
-+struct command_table_helper {
-+ bool (*controller_id_to_atom)(enum controller_id id, uint8_t *atom_id);
-+ uint8_t (*encoder_action_to_atom)(
-+ enum bp_encoder_control_action action);
-+ uint32_t (*encoder_mode_bp_to_atom)(enum signal_type s,
-+ bool enable_dp_audio);
-+ bool (*engine_bp_to_atom)(enum engine_id engine_id,
-+ uint32_t *atom_engine_id);
-+ void (*assign_control_parameter)(
-+ const struct command_table_helper *h,
-+ struct bp_encoder_control *control,
-+ DIG_ENCODER_CONTROL_PARAMETERS_V2 *ctrl_param);
-+ bool (*clock_source_id_to_atom)(enum clock_source_id id,
-+ uint32_t *atom_pll_id);
-+ bool (*clock_source_id_to_ref_clk_src)(
-+ enum clock_source_id id,
-+ uint32_t *ref_clk_src_id);
-+ uint8_t (*transmitter_bp_to_atom)(enum transmitter t);
-+ uint8_t (*encoder_id_to_atom)(enum encoder_id id);
-+ uint8_t (*clock_source_id_to_atom_phy_clk_src_id)(
-+ enum clock_source_id id);
-+ uint8_t (*signal_type_to_atom_dig_mode)(enum signal_type s);
-+ uint8_t (*hpd_sel_to_atom)(enum hpd_source_id id);
-+ uint8_t (*dig_encoder_sel_to_atom)(enum engine_id engine_id);
-+ uint8_t (*phy_id_to_atom)(enum transmitter t);
-+ uint8_t (*disp_power_gating_action_to_atom)(
-+ enum bp_pipe_control_action action);
-+};
-+
-+bool dal_bios_parser_init_cmd_tbl_helper(const struct command_table_helper **h,
-+ enum dce_version dce);
-+
-+bool dal_cmd_table_helper_controller_id_to_atom(
-+ enum controller_id id,
-+ uint8_t *atom_id);
-+
-+uint32_t dal_cmd_table_helper_encoder_mode_bp_to_atom(
-+ enum signal_type s,
-+ bool enable_dp_audio);
-+
-+void dal_cmd_table_helper_assign_control_parameter(
-+ const struct command_table_helper *h,
-+ struct bp_encoder_control *control,
-+DIG_ENCODER_CONTROL_PARAMETERS_V2 *ctrl_param);
-+
-+bool dal_cmd_table_helper_clock_source_id_to_ref_clk_src(
-+ enum clock_source_id id,
-+ uint32_t *ref_clk_src_id);
-+
-+uint8_t dal_cmd_table_helper_transmitter_bp_to_atom(
-+ enum transmitter t);
-+
-+uint8_t dal_cmd_table_helper_encoder_id_to_atom(
-+ enum encoder_id id);
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/dce110/bios_parser_helper_dce110.c b/drivers/gpu/drm/amd/dal/dc/bios/dce110/bios_parser_helper_dce110.c
-new file mode 100644
-index 0000000..2cc2d2d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/dce110/bios_parser_helper_dce110.c
-@@ -0,0 +1,484 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "atom.h"
-+
-+#include "include/bios_parser_types.h"
-+#include "include/adapter_service_types.h"
-+#include "include/logger_interface.h"
-+
-+#include "../bios_parser_helper.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "bif/bif_5_1_d.h"
-+
-+/**
-+ * set_scratch_acc_mode_change
-+ *
-+ * @brief
-+ * set Accelerated Mode in VBIOS scratch register, VBIOS will clean it when
-+ * VGA/non-Accelerated mode is set
-+ *
-+ * @param
-+ * struct dc_context *ctx - [in] DAL context
-+ */
-+static void set_scratch_acc_mode_change(
-+ struct dc_context *ctx)
-+{
-+ uint32_t addr = mmBIOS_SCRATCH_6;
-+ uint32_t value = 0;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ value |= ATOM_S6_ACC_MODE;
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+/*
-+ * set_scratch_active_and_requested
-+ *
-+ * @brief
-+ * Set VBIOS scratch pad registers about active and requested displays
-+ *
-+ * @param
-+ * struct dc_context *ctx - [in] DAL context for register accessing
-+ * struct vbios_helper_data *d - [in] values to write
-+ */
-+static void set_scratch_active_and_requested(
-+ struct dc_context *ctx,
-+ struct vbios_helper_data *d)
-+{
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+
-+ /* mmBIOS_SCRATCH_3 = mmBIOS_SCRATCH_0 + ATOM_ACTIVE_INFO_DEF */
-+ addr = mmBIOS_SCRATCH_3;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ value &= ~ATOM_S3_DEVICE_ACTIVE_MASK;
-+ value |= (d->active & ATOM_S3_DEVICE_ACTIVE_MASK);
-+
-+ dal_write_reg(ctx, addr, value);
-+
-+ /* mmBIOS_SCRATCH_6 = mmBIOS_SCRATCH_0 + ATOM_ACC_CHANGE_INFO_DEF */
-+ addr = mmBIOS_SCRATCH_6;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ value &= ~ATOM_S6_ACC_REQ_MASK;
-+ value |= (d->requested & ATOM_S6_ACC_REQ_MASK);
-+
-+ dal_write_reg(ctx, addr, value);
-+
-+ /* mmBIOS_SCRATCH_5 = mmBIOS_SCRATCH_0 + ATOM_DOS_REQ_INFO_DEF */
-+ addr = mmBIOS_SCRATCH_5;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ value &= ~ATOM_S5_DOS_REQ_DEVICEw0;
-+ value |= (d->active & ATOM_S5_DOS_REQ_DEVICEw0);
-+
-+ dal_write_reg(ctx, addr, value);
-+
-+ d->active = 0;
-+ d->requested = 0;
-+}
-+
-+/**
-+ * get LCD Scale Mode from VBIOS scratch register
-+ */
-+static enum lcd_scale get_scratch_lcd_scale(
-+ struct dc_context *ctx)
-+{
-+ uint32_t addr = mmBIOS_SCRATCH_6;
-+ uint32_t value = 0;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ if (value & ATOM_S6_REQ_LCD_EXPANSION_FULL)
-+ return LCD_SCALE_FULLPANEL;
-+ else if (value & ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIO)
-+ return LCD_SCALE_ASPECTRATIO;
-+ else
-+ return LCD_SCALE_NONE;
-+}
-+
-+/**
-+ * prepare_scratch_active_and_requested
-+ *
-+ * @brief
-+ * prepare and update VBIOS scratch pad registers about active and requested
-+ * displays
-+ *
-+ * @param
-+ * data - helper's shared data
-+ * enum controller_ild - controller Id
-+ * enum signal_type - signal type used on display
-+ * const struct connector_device_tag_info* - pointer to display type and enum id
-+ */
-+static void prepare_scratch_active_and_requested(
-+ struct dc_context *ctx,
-+ struct vbios_helper_data *data,
-+ enum controller_id id,
-+ enum signal_type s,
-+ const struct connector_device_tag_info *dev_tag)
-+{
-+ switch (s) {
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
-+ case SIGNAL_TYPE_DVI_DUAL_LINK:
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ if (dev_tag->dev_id.device_type == DEVICE_TYPE_DFP)
-+ switch (dev_tag->dev_id.enum_id) {
-+ case 1:
-+ data->requested |= ATOM_S6_ACC_REQ_DFP1;
-+ data->active |= ATOM_S3_DFP1_ACTIVE;
-+ break;
-+ case 2:
-+ data->requested |= ATOM_S6_ACC_REQ_DFP2;
-+ data->active |= ATOM_S3_DFP2_ACTIVE;
-+ break;
-+ case 3:
-+ data->requested |= ATOM_S6_ACC_REQ_DFP3;
-+ data->active |= ATOM_S3_DFP3_ACTIVE;
-+ break;
-+ case 4:
-+ data->requested |= ATOM_S6_ACC_REQ_DFP4;
-+ data->active |= ATOM_S3_DFP4_ACTIVE;
-+ break;
-+ case 5:
-+ data->requested |= ATOM_S6_ACC_REQ_DFP5;
-+ data->active |= ATOM_S3_DFP5_ACTIVE;
-+ break;
-+ case 6:
-+ data->requested |= ATOM_S6_ACC_REQ_DFP6;
-+ data->active |= ATOM_S3_DFP6_ACTIVE;
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+ case SIGNAL_TYPE_LVDS:
-+ case SIGNAL_TYPE_EDP:
-+ data->requested |= ATOM_S6_ACC_REQ_LCD1;
-+ data->active |= ATOM_S3_LCD1_ACTIVE;
-+ break;
-+ case SIGNAL_TYPE_RGB:
-+ if (dev_tag->dev_id.device_type == DEVICE_TYPE_CRT)
-+ switch (dev_tag->dev_id.enum_id) {
-+ case 1:
-+ data->requested |= ATOM_S6_ACC_REQ_CRT1;
-+ data->active |= ATOM_S3_CRT1_ACTIVE;
-+ break;
-+ case 2:
-+ dal_logger_write(ctx->logger,
-+ LOG_MAJOR_BIOS,
-+ LOG_MINOR_COMPONENT_BIOS,
-+ "%s: DAL does not support DAC2!\n",
-+ __func__);
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+ default:
-+ dal_logger_write(ctx->logger,
-+ LOG_MAJOR_BIOS,
-+ LOG_MINOR_COMPONENT_BIOS,
-+ "%s: No such signal!\n",
-+ __func__);
-+ break;
-+ }
-+}
-+
-+/*
-+ * is_accelerated_mode
-+ *
-+ * @brief
-+ * set Accelerated Mode in VBIOS scratch register, VBIOS will clean it when
-+ * VGA/non-Accelerated mode is set
-+ *
-+ * @param
-+ * struct dc_context *ctx
-+ *
-+ * @return
-+ * true if in acceleration mode, false otherwise.
-+ */
-+static bool is_accelerated_mode(
-+ struct dc_context *ctx)
-+{
-+ uint32_t addr = mmBIOS_SCRATCH_6;
-+ uint32_t value = dal_read_reg(ctx, addr);
-+
-+ return (value & ATOM_S6_ACC_MODE) ? true : false;
-+}
-+
-+#define BIOS_SCRATCH0_DAC_B_SHIFT 8
-+
-+/**
-+ * detect_sink
-+ *
-+ * @brief
-+ * read VBIOS scratch register to determine whether display for the specified
-+ * signal is present and return the actual sink signal type
-+ * For analog signals VBIOS load detection has to be called prior reading the
-+ * register
-+ *
-+ * @param
-+ * encoder - encoder id (to specify DAC)
-+ * connector - connector id (to check CV on DIN)
-+ * signal - signal (as display type) to check
-+ *
-+ * @return
-+ * signal_type - actual (on the sink) signal type detected
-+ */
-+static enum signal_type detect_sink(
-+ struct dc_context *ctx,
-+ struct graphics_object_id encoder,
-+ struct graphics_object_id connector,
-+ enum signal_type signal)
-+{
-+ uint32_t bios_scratch0;
-+ uint32_t encoder_id = encoder.id;
-+ /* after DCE 10.x does not support DAC2, so assert and return
-+ * SIGNAL_TYPE_NONE */
-+ if (encoder_id == ENCODER_ID_INTERNAL_DAC2
-+ || encoder_id == ENCODER_ID_INTERNAL_KLDSCP_DAC2) {
-+ ASSERT(false);
-+ return SIGNAL_TYPE_NONE;
-+ }
-+
-+ bios_scratch0 = dal_read_reg(ctx,
-+ mmBIOS_SCRATCH_0 + ATOM_DEVICE_CONNECT_INFO_DEF);
-+
-+ /* In further processing we use DACB masks. If we want detect load on
-+ * DACA, we need to shift the register so DACA bits will be in place of
-+ * DACB bits
-+ */
-+ if (encoder_id == ENCODER_ID_INTERNAL_DAC1
-+ || encoder_id == ENCODER_ID_INTERNAL_KLDSCP_DAC1
-+ || encoder_id == ENCODER_ID_EXTERNAL_NUTMEG
-+ || encoder_id == ENCODER_ID_EXTERNAL_TRAVIS) {
-+ bios_scratch0 <<= BIOS_SCRATCH0_DAC_B_SHIFT;
-+ }
-+
-+ switch (signal) {
-+ case SIGNAL_TYPE_RGB: {
-+ if (bios_scratch0 & ATOM_S0_CRT2_MASK)
-+ return SIGNAL_TYPE_RGB;
-+ break;
-+ }
-+ case SIGNAL_TYPE_LVDS: {
-+ if (bios_scratch0 & ATOM_S0_LCD1)
-+ return SIGNAL_TYPE_LVDS;
-+ break;
-+ }
-+ case SIGNAL_TYPE_EDP: {
-+ if (bios_scratch0 & ATOM_S0_LCD1)
-+ return SIGNAL_TYPE_EDP;
-+ break;
-+ }
-+ default:
-+ break;
-+ }
-+
-+ return SIGNAL_TYPE_NONE;
-+}
-+
-+/**
-+ * set_scratch_connected
-+ *
-+ * @brief
-+ * update BIOS_SCRATCH_0 register about connected displays
-+ *
-+ * @param
-+ * bool - update scratch register or just prepare info to be updated
-+ * bool - connection state
-+ * const struct connector_device_tag_info * - pointer to device type and enum ID
-+ */
-+static void set_scratch_connected(
-+ struct dc_context *ctx,
-+ struct graphics_object_id id,
-+ bool connected,
-+ const struct connector_device_tag_info *device_tag)
-+{
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+ uint32_t update = 0;
-+
-+ switch (device_tag->dev_id.device_type) {
-+ case DEVICE_TYPE_LCD:
-+ /* For LCD VBIOS will update LCD Panel connected bit always and
-+ * Lid state bit based on SBIOS info do not do anything here
-+ * for LCD
-+ */
-+ break;
-+ case DEVICE_TYPE_CRT:
-+ /*
-+ * CRT is not supported in DCE11
-+ */
-+ break;
-+ case DEVICE_TYPE_DFP:
-+ switch (device_tag->dev_id.enum_id) {
-+ case 1:
-+ update |= ATOM_S0_DFP1;
-+ break;
-+ case 2:
-+ update |= ATOM_S0_DFP2;
-+ break;
-+ case 3:
-+ update |= ATOM_S0_DFP3;
-+ break;
-+ case 4:
-+ update |= ATOM_S0_DFP4;
-+ break;
-+ case 5:
-+ update |= ATOM_S0_DFP5;
-+ break;
-+ case 6:
-+ update |= ATOM_S0_DFP6;
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+ case DEVICE_TYPE_CV:
-+ /* DCE 8.0 does not support CV,
-+ * so don't do anything */
-+ break;
-+
-+ case DEVICE_TYPE_TV:
-+ /* For TV VBIOS will update S-Video or
-+ * Composite scratch bits on DAL_LoadDetect
-+ * when called by driver, do not do anything
-+ * here for TV
-+ */
-+ break;
-+
-+ default:
-+ break;
-+
-+ }
-+
-+ /* update scratch register */
-+ addr = mmBIOS_SCRATCH_0 + ATOM_DEVICE_CONNECT_INFO_DEF;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ if (connected)
-+ value |= update;
-+ else
-+ value &= ~update;
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+static void set_scratch_critical_state(
-+ struct dc_context *ctx,
-+ bool state)
-+{
-+ uint32_t addr = mmBIOS_SCRATCH_6;
-+ uint32_t value = dal_read_reg(ctx, addr);
-+
-+ if (state)
-+ value |= ATOM_S6_CRITICAL_STATE;
-+ else
-+ value &= ~ATOM_S6_CRITICAL_STATE;
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+static void set_scratch_lcd_scale(
-+ struct dc_context *ctx,
-+ enum lcd_scale lcd_scale_request)
-+{
-+ DAL_LOGGER_NOT_IMPL(
-+ LOG_MINOR_COMPONENT_BIOS,
-+ "Bios Parser:%s\n",
-+ __func__);
-+}
-+
-+static bool is_lid_open(struct dc_context *ctx)
-+{
-+ uint32_t bios_scratch6;
-+
-+ bios_scratch6 =
-+ dal_read_reg(
-+ ctx,
-+ mmBIOS_SCRATCH_0 + ATOM_ACC_CHANGE_INFO_DEF);
-+
-+ /* lid is open if the bit is not set */
-+ if (!(bios_scratch6 & ATOM_S6_LID_STATE))
-+ return true;
-+
-+ return false;
-+}
-+
-+/* function table */
-+static const struct bios_parser_helper bios_parser_helper_funcs = {
-+ .detect_sink = detect_sink,
-+ .fmt_bit_depth_control = NULL,
-+ .fmt_control = NULL,
-+ .get_bios_event_info = NULL,
-+ .get_embedded_display_controller_id = NULL,
-+ .get_embedded_display_refresh_rate = NULL,
-+ .get_requested_backlight_level = NULL,
-+ .get_scratch_lcd_scale = get_scratch_lcd_scale,
-+ .is_accelerated_mode = is_accelerated_mode,
-+ .is_active_display = NULL,
-+ .is_display_config_changed = NULL,
-+ .is_lid_open = is_lid_open,
-+ .is_lid_status_changed = NULL,
-+ .prepare_scratch_active_and_requested =
-+ prepare_scratch_active_and_requested,
-+ .set_scratch_acc_mode_change = set_scratch_acc_mode_change,
-+ .set_scratch_active_and_requested = set_scratch_active_and_requested,
-+ .set_scratch_connected = set_scratch_connected,
-+ .set_scratch_critical_state = set_scratch_critical_state,
-+ .set_scratch_lcd_scale = set_scratch_lcd_scale,
-+ .take_backlight_control = NULL,
-+ .update_requested_backlight_level = NULL,
-+};
-+
-+/*
-+ * dal_bios_parser_dce110_init_bios_helper
-+ *
-+ * @brief
-+ * Initialize BIOS helper functions
-+ *
-+ * @param
-+ * const struct command_table_helper **h - [out] struct of functions
-+ *
-+ */
-+
-+const struct bios_parser_helper *dal_bios_parser_helper_dce110_get_table()
-+{
-+ return &bios_parser_helper_funcs;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/dce110/bios_parser_helper_dce110.h b/drivers/gpu/drm/amd/dal/dc/bios/dce110/bios_parser_helper_dce110.h
-new file mode 100644
-index 0000000..915f31a
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/dce110/bios_parser_helper_dce110.h
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_BIOS_PARSER_HELPER_DCE110_H__
-+#define __DAL_BIOS_PARSER_HELPER_DCE110_H__
-+
-+struct bios_parser_helper;
-+
-+/* Initialize BIOS helper functions */
-+const struct bios_parser_helper *dal_bios_parser_helper_dce110_get_table(void);
-+
-+#endif /* __DAL_BIOS_PARSER_HELPER_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/dce110/command_table_helper_dce110.c b/drivers/gpu/drm/amd/dal/dc/bios/dce110/command_table_helper_dce110.c
-new file mode 100644
-index 0000000..e75b51b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/dce110/command_table_helper_dce110.c
-@@ -0,0 +1,369 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "atom.h"
-+
-+#include "include/bios_parser_types.h"
-+#include "include/adapter_service_types.h"
-+
-+#include "../command_table_helper.h"
-+
-+static uint8_t phy_id_to_atom(enum transmitter t)
-+{
-+ uint8_t atom_phy_id;
-+
-+ switch (t) {
-+ case TRANSMITTER_UNIPHY_A:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYA;
-+ break;
-+ case TRANSMITTER_UNIPHY_B:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYB;
-+ break;
-+ case TRANSMITTER_UNIPHY_C:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYC;
-+ break;
-+ case TRANSMITTER_UNIPHY_D:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYD;
-+ break;
-+ case TRANSMITTER_UNIPHY_E:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYE;
-+ break;
-+ case TRANSMITTER_UNIPHY_F:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYF;
-+ break;
-+ case TRANSMITTER_UNIPHY_G:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYG;
-+ break;
-+ default:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYA;
-+ break;
-+ }
-+ return atom_phy_id;
-+}
-+
-+
-+static uint8_t signal_type_to_atom_dig_mode(enum signal_type s)
-+{
-+ uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP;
-+
-+ switch (s) {
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_EDP:
-+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP;
-+ break;
-+ case SIGNAL_TYPE_LVDS:
-+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_LVDS;
-+ break;
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
-+ case SIGNAL_TYPE_DVI_DUAL_LINK:
-+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DVI;
-+ break;
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_HDMI;
-+ break;
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DP_MST;
-+ break;
-+ default:
-+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V5_DVI;
-+ break;
-+ }
-+
-+ return atom_dig_mode;
-+}
-+
-+static uint8_t clock_source_id_to_atom_phy_clk_src_id(
-+ enum clock_source_id id)
-+{
-+ uint8_t atom_phy_clk_src_id = 0;
-+
-+ switch (id) {
-+ case CLOCK_SOURCE_ID_PLL0:
-+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL;
-+ break;
-+ case CLOCK_SOURCE_ID_PLL1:
-+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
-+ break;
-+ case CLOCK_SOURCE_ID_PLL2:
-+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL;
-+ break;
-+ case CLOCK_SOURCE_ID_EXTERNAL:
-+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT;
-+ break;
-+ default:
-+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
-+ break;
-+ }
-+
-+ return atom_phy_clk_src_id >> 2;
-+}
-+
-+static uint8_t hpd_sel_to_atom(enum hpd_source_id id)
-+{
-+ uint8_t atom_hpd_sel = 0;
-+
-+ switch (id) {
-+ case HPD_SOURCEID1:
-+ atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD1_SEL;
-+ break;
-+ case HPD_SOURCEID2:
-+ atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD2_SEL;
-+ break;
-+ case HPD_SOURCEID3:
-+ atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD3_SEL;
-+ break;
-+ case HPD_SOURCEID4:
-+ atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD4_SEL;
-+ break;
-+ case HPD_SOURCEID5:
-+ atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD5_SEL;
-+ break;
-+ case HPD_SOURCEID6:
-+ atom_hpd_sel = ATOM_TRANSMITTER_CONFIG_V5_HPD6_SEL;
-+ break;
-+ case HPD_SOURCEID_UNKNOWN:
-+ default:
-+ atom_hpd_sel = 0;
-+ break;
-+ }
-+ return atom_hpd_sel >> 4;
-+}
-+
-+static uint8_t dig_encoder_sel_to_atom(enum engine_id id)
-+{
-+ uint8_t atom_dig_encoder_sel = 0;
-+
-+ switch (id) {
-+ case ENGINE_ID_DIGA:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGA_SEL;
-+ break;
-+ case ENGINE_ID_DIGB:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGB_SEL;
-+ break;
-+ case ENGINE_ID_DIGC:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGC_SEL;
-+ break;
-+ case ENGINE_ID_DIGD:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGD_SEL;
-+ break;
-+ case ENGINE_ID_DIGE:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGE_SEL;
-+ break;
-+ case ENGINE_ID_DIGF:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGF_SEL;
-+ break;
-+ case ENGINE_ID_DIGG:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGG_SEL;
-+ break;
-+ case ENGINE_ID_UNKNOWN:
-+ /* No DIG_FRONT is associated to DIG_BACKEND */
-+ atom_dig_encoder_sel = 0;
-+ break;
-+ default:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGA_SEL;
-+ break;
-+ }
-+
-+ return atom_dig_encoder_sel;
-+}
-+
-+static bool clock_source_id_to_atom(
-+ enum clock_source_id id,
-+ uint32_t *atom_pll_id)
-+{
-+ bool result = true;
-+
-+ if (atom_pll_id != NULL)
-+ switch (id) {
-+ case CLOCK_SOURCE_ID_PLL0:
-+ *atom_pll_id = ATOM_PPLL0;
-+ break;
-+ case CLOCK_SOURCE_ID_PLL1:
-+ *atom_pll_id = ATOM_PPLL1;
-+ break;
-+ case CLOCK_SOURCE_ID_PLL2:
-+ *atom_pll_id = ATOM_PPLL2;
-+ break;
-+ case CLOCK_SOURCE_ID_EXTERNAL:
-+ *atom_pll_id = ATOM_PPLL_INVALID;
-+ break;
-+ case CLOCK_SOURCE_ID_DFS:
-+ *atom_pll_id = ATOM_EXT_PLL1;
-+ break;
-+ case CLOCK_SOURCE_ID_VCE:
-+ /* for VCE encoding,
-+ * we need to pass in ATOM_PPLL_INVALID
-+ */
-+ *atom_pll_id = ATOM_PPLL_INVALID;
-+ break;
-+ case CLOCK_SOURCE_ID_DP_DTO:
-+ /* When programming DP DTO PLL ID should be invalid */
-+ *atom_pll_id = ATOM_PPLL_INVALID;
-+ break;
-+ case CLOCK_SOURCE_ID_UNDEFINED:
-+ /* Should not happen */
-+ *atom_pll_id = ATOM_PPLL_INVALID;
-+ result = false;
-+ break;
-+ default:
-+ result = false;
-+ break;
-+ }
-+
-+ return result;
-+}
-+
-+static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id)
-+{
-+ bool result = false;
-+
-+ if (atom_engine_id != NULL)
-+ switch (id) {
-+ case ENGINE_ID_DIGA:
-+ *atom_engine_id = ASIC_INT_DIG1_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DIGB:
-+ *atom_engine_id = ASIC_INT_DIG2_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DIGC:
-+ *atom_engine_id = ASIC_INT_DIG3_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DIGD:
-+ *atom_engine_id = ASIC_INT_DIG4_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DIGE:
-+ *atom_engine_id = ASIC_INT_DIG5_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DIGF:
-+ *atom_engine_id = ASIC_INT_DIG6_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DIGG:
-+ *atom_engine_id = ASIC_INT_DIG7_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DVO:
-+ *atom_engine_id = ASIC_EXT_DIG_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DACA:
-+ *atom_engine_id = ASIC_INT_DAC1_ENCODER_ID;
-+ result = true;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return result;
-+}
-+
-+static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action)
-+{
-+ uint8_t atom_action = 0;
-+
-+ switch (action) {
-+ case ENCODER_CONTROL_ENABLE:
-+ atom_action = ATOM_ENABLE;
-+ break;
-+ case ENCODER_CONTROL_DISABLE:
-+ atom_action = ATOM_DISABLE;
-+ break;
-+ case ENCODER_CONTROL_SETUP:
-+ atom_action = ATOM_ENCODER_CMD_SETUP;
-+ break;
-+ case ENCODER_CONTROL_INIT:
-+ atom_action = ATOM_ENCODER_INIT;
-+ break;
-+ default:
-+ BREAK_TO_DEBUGGER(); /* Unhandle action in driver.!! */
-+ break;
-+ }
-+
-+ return atom_action;
-+}
-+
-+static uint8_t disp_power_gating_action_to_atom(
-+ enum bp_pipe_control_action action)
-+{
-+ uint8_t atom_pipe_action = 0;
-+
-+ switch (action) {
-+ case ASIC_PIPE_DISABLE:
-+ atom_pipe_action = ATOM_DISABLE;
-+ break;
-+ case ASIC_PIPE_ENABLE:
-+ atom_pipe_action = ATOM_ENABLE;
-+ break;
-+ case ASIC_PIPE_INIT:
-+ atom_pipe_action = ATOM_INIT;
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false); /* Unhandle action in driver! */
-+ break;
-+ }
-+
-+ return atom_pipe_action;
-+}
-+
-+/* function table */
-+static const struct command_table_helper command_table_helper_funcs = {
-+ .controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom,
-+ .encoder_action_to_atom = encoder_action_to_atom,
-+ .engine_bp_to_atom = engine_bp_to_atom,
-+ .clock_source_id_to_atom = clock_source_id_to_atom,
-+ .clock_source_id_to_atom_phy_clk_src_id =
-+ clock_source_id_to_atom_phy_clk_src_id,
-+ .signal_type_to_atom_dig_mode = signal_type_to_atom_dig_mode,
-+ .hpd_sel_to_atom = hpd_sel_to_atom,
-+ .dig_encoder_sel_to_atom = dig_encoder_sel_to_atom,
-+ .phy_id_to_atom = phy_id_to_atom,
-+ .disp_power_gating_action_to_atom = disp_power_gating_action_to_atom,
-+ .assign_control_parameter = NULL,
-+ .clock_source_id_to_ref_clk_src = NULL,
-+ .transmitter_bp_to_atom = NULL,
-+ .encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom,
-+ .encoder_mode_bp_to_atom = dal_cmd_table_helper_encoder_mode_bp_to_atom,
-+};
-+
-+/*
-+ * dal_cmd_tbl_helper_dce110_get_table
-+ *
-+ * @brief
-+ * Initialize command table helper functions
-+ *
-+ * @param
-+ * const struct command_table_helper **h - [out] struct of functions
-+ *
-+ */
-+const struct command_table_helper *dal_cmd_tbl_helper_dce110_get_table()
-+{
-+ return &command_table_helper_funcs;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/dce110/command_table_helper_dce110.h b/drivers/gpu/drm/amd/dal/dc/bios/dce110/command_table_helper_dce110.h
-new file mode 100644
-index 0000000..eb60c2e
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/dce110/command_table_helper_dce110.h
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_COMMAND_TABLE_HELPER_DCE110_H__
-+#define __DAL_COMMAND_TABLE_HELPER_DCE110_H__
-+
-+struct command_table_helper;
-+
-+/* Initialize command table helper functions */
-+const struct command_table_helper *dal_cmd_tbl_helper_dce110_get_table(void);
-+
-+#endif /* __DAL_COMMAND_TABLE_HELPER_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/calcs/Makefile b/drivers/gpu/drm/amd/dal/dc/calcs/Makefile
-new file mode 100644
-index 0000000..7f1916b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/calcs/Makefile
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the 'calcs' sub-component of DAL.
-+# It calculates Bandwidth and Watermarks values for HW programming
-+#
-+
-+BW_CALCS = bandwidth_calcs.o bw_fixed.o scaler_filter.o
-+
-+AMD_DAL_BW_CALCS = $(addprefix $(AMDDALPATH)/dc/calcs/,$(BW_CALCS))
-+
-+AMD_DAL_FILES += $(AMD_DAL_BW_CALCS)
-diff --git a/drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c b/drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c
-new file mode 100644
-index 0000000..68618bb
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c
-@@ -0,0 +1,3478 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dc_services.h"
-+
-+#include "bandwidth_calcs.h"
-+
-+/*******************************************************************************
-+ * Private Functions
-+ ******************************************************************************/
-+
-+enum bw_defines {
-+ def_ok,
-+ def_na,
-+ def_notok,
-+ def_display_write_back420_chroma,
-+ def_display_write_back420_luma,
-+ def_graphics,
-+ def_xl_pattern_solid,
-+ def_xl_pattern_light_horizontal,
-+ def_xl_pattern_checker,
-+ def_notok_color,
-+ def_na_color,
-+ def_vb_black,
-+ def_vb_white,
-+ def_high_no_nbp_state_change_color,
-+ def_high_no_nbp_state_change,
-+ def_high_color,
-+ def_mid_color,
-+ def_low_color,
-+ def_high,
-+ def_mid,
-+ def_low,
-+ def_exceeded_allowed_maximum_sclk,
-+ def_exceeded_allowed_maximum_bw,
-+ def_exceeded_allowed_page_close_open,
-+ def_exceeded_allowed_outstanding_pte_req_queue_size,
-+ def_linear,
-+ def_underlay444,
-+ def_underlay422,
-+ def_underlay420_chroma,
-+ def_underlay420_luma,
-+ def_any_lines,
-+ def_auto,
-+ def_manual,
-+ def_portrait,
-+ def_invalid_linear_or_stereo_mode,
-+ def_invalid_rotation_or_bpp_or_stereo,
-+ def_vsr_more_than_vtaps,
-+ def_vsr_more_than_4,
-+ def_ceil_htaps_div_4_more_or_eq_hsr,
-+ def_hsr_more_than_htaps,
-+ def_hsr_more_than_4,
-+ def_none,
-+ def_blended,
-+ def_landscape
-+};
-+
-+static void calculate_bandwidth(const struct bw_calcs_input_dceip *dceip,
-+ const struct bw_calcs_input_vbios *vbios,
-+ const struct bw_calcs_input_mode_data_internal *mode_data,
-+ struct bw_results_internal *results)
-+{
-+ const struct bw_fixed pixels_per_chunk = int_to_fixed(512);
-+ const struct bw_fixed max_chunks_non_fbc_mode = int_to_fixed(16);
-+ const uint32_t high = 2;
-+ const uint32_t mid = 1;
-+ const uint32_t low = 0;
-+
-+ uint32_t i, j, k;
-+ struct bw_fixed yclk[3];
-+ struct bw_fixed sclk[3];
-+ bool d0_underlay_enable;
-+ bool d1_underlay_enable;
-+ enum bw_defines v_filter_init_mode[maximum_number_of_surfaces];
-+ enum bw_defines tiling_mode[maximum_number_of_surfaces];
-+ enum bw_stereo_mode stereo_mode[maximum_number_of_surfaces];
-+ enum bw_defines surface_type[maximum_number_of_surfaces];
-+ enum bw_defines voltage;
-+ enum bw_defines mode_background_color;
-+ enum bw_defines mode_font_color;
-+ enum bw_defines mode_pattern;
-+ enum bw_defines sclk_message;
-+ enum bw_defines yclk_message;
-+ enum bw_defines pipe_check;
-+ enum bw_defines hsr_check;
-+ enum bw_defines vsr_check;
-+ enum bw_defines lb_size_check;
-+ enum bw_defines fbc_check;
-+ enum bw_defines rotation_check;
-+ enum bw_defines mode_check;
-+ uint32_t y_clk_level;
-+ uint32_t sclk_level;
-+ yclk[high] = vbios->high_yclk;
-+ yclk[mid] = vbios->high_yclk;
-+ yclk[low] = vbios->low_yclk;
-+ sclk[high] = vbios->high_sclk;
-+ sclk[mid] = vbios->mid_sclk;
-+ sclk[low] = vbios->low_sclk;
-+ if (mode_data->d0_underlay_mode == ul_none) {
-+ d0_underlay_enable = false;
-+ } else {
-+ d0_underlay_enable = true;
-+ }
-+ if (mode_data->d1_underlay_mode == ul_none) {
-+ d1_underlay_enable = false;
-+ } else {
-+ d1_underlay_enable = true;
-+ }
-+ results->number_of_underlay_surfaces = int_to_fixed(
-+ d0_underlay_enable + d1_underlay_enable);
-+ if (mode_data->underlay_surface_type == yuv_420) {
-+ surface_type[0] = def_underlay420_luma;
-+ surface_type[2] = def_underlay420_luma;
-+ results->bytes_per_pixel[0] = int_to_fixed(1);
-+ results->bytes_per_pixel[2] = int_to_fixed(1);
-+ surface_type[1] = def_underlay420_chroma;
-+ surface_type[3] = def_underlay420_chroma;
-+ results->bytes_per_pixel[1] = int_to_fixed(2);
-+ results->bytes_per_pixel[3] = int_to_fixed(2);
-+ results->lb_size_per_component[0] =
-+ dceip->underlay420_luma_lb_size_per_component;
-+ results->lb_size_per_component[1] =
-+ dceip->underlay420_chroma_lb_size_per_component;
-+ results->lb_size_per_component[2] =
-+ dceip->underlay420_luma_lb_size_per_component;
-+ results->lb_size_per_component[3] =
-+ dceip->underlay420_chroma_lb_size_per_component;
-+ } else if (mode_data->underlay_surface_type == yuv_422) {
-+ surface_type[0] = def_underlay422;
-+ surface_type[2] = def_underlay422;
-+ results->bytes_per_pixel[0] = int_to_fixed(2);
-+ results->bytes_per_pixel[2] = int_to_fixed(2);
-+ results->lb_size_per_component[0] =
-+ dceip->underlay422_lb_size_per_component;
-+ results->lb_size_per_component[2] =
-+ dceip->underlay422_lb_size_per_component;
-+ } else {
-+ surface_type[0] = def_underlay444;
-+ surface_type[2] = def_underlay444;
-+ results->bytes_per_pixel[0] = int_to_fixed(4);
-+ results->bytes_per_pixel[2] = int_to_fixed(4);
-+ results->lb_size_per_component[0] =
-+ dceip->lb_size_per_component444;
-+ results->lb_size_per_component[2] =
-+ dceip->lb_size_per_component444;
-+ }
-+ if (d0_underlay_enable) {
-+ if (mode_data->underlay_surface_type == yuv_420) {
-+ results->enable[0] = true;
-+ results->enable[1] = true;
-+ } else {
-+ results->enable[0] = true;
-+ results->enable[1] = false;
-+ }
-+ } else {
-+ results->enable[0] = false;
-+ results->enable[1] = false;
-+ }
-+ if (d1_underlay_enable) {
-+ if (mode_data->underlay_surface_type == yuv_420) {
-+ results->enable[2] = true;
-+ results->enable[3] = true;
-+ } else {
-+ results->enable[2] = true;
-+ results->enable[3] = false;
-+ }
-+ } else {
-+ results->enable[2] = false;
-+ results->enable[3] = false;
-+ }
-+
-+ results->use_alpha[0] = false;
-+ results->use_alpha[1] = false;
-+ results->use_alpha[2] = false;
-+ results->use_alpha[3] = false;
-+ results->scatter_gather_enable_for_pipe[0] =
-+ vbios->scatter_gather_enable;
-+ results->scatter_gather_enable_for_pipe[1] =
-+ vbios->scatter_gather_enable;
-+ results->scatter_gather_enable_for_pipe[2] =
-+ vbios->scatter_gather_enable;
-+ results->scatter_gather_enable_for_pipe[3] =
-+ vbios->scatter_gather_enable;
-+ results->interlace_mode[0] = mode_data->graphics_interlace_mode;
-+ results->interlace_mode[1] = mode_data->graphics_interlace_mode;
-+ results->interlace_mode[2] = mode_data->graphics_interlace_mode;
-+ results->interlace_mode[3] = mode_data->graphics_interlace_mode;
-+ results->h_total[0] = mode_data->d0_htotal;
-+ results->h_total[1] = mode_data->d0_htotal;
-+ results->h_total[2] = mode_data->d1_htotal;
-+ results->h_total[3] = mode_data->d1_htotal;
-+ results->pixel_rate[0] = mode_data->d0_pixel_rate;
-+ results->pixel_rate[1] = mode_data->d0_pixel_rate;
-+ results->pixel_rate[2] = mode_data->d1_pixel_rate;
-+ results->pixel_rate[3] = mode_data->d1_pixel_rate;
-+ results->src_width[0] = mode_data->underlay_src_width;
-+ results->src_width[1] = mode_data->underlay_src_width;
-+ results->src_width[2] = mode_data->underlay_src_width;
-+ results->src_width[3] = mode_data->underlay_src_width;
-+ results->src_height[0] = mode_data->underlay_src_height;
-+ results->src_height[1] = mode_data->underlay_src_height;
-+ results->src_height[2] = mode_data->underlay_src_height;
-+ results->src_height[3] = mode_data->underlay_src_height;
-+ results->pitch_in_pixels[0] = mode_data->underlay_pitch_in_pixels;
-+ results->pitch_in_pixels[1] = mode_data->underlay_pitch_in_pixels;
-+ results->pitch_in_pixels[2] = mode_data->underlay_pitch_in_pixels;
-+ results->pitch_in_pixels[3] = mode_data->underlay_pitch_in_pixels;
-+ results->scale_ratio[0] = mode_data->d0_underlay_scale_ratio;
-+ results->scale_ratio[1] = mode_data->d0_underlay_scale_ratio;
-+ results->scale_ratio[2] = mode_data->d1_underlay_scale_ratio;
-+ results->scale_ratio[3] = mode_data->d1_underlay_scale_ratio;
-+ results->h_taps[0] = mode_data->underlay_htaps;
-+ results->h_taps[1] = mode_data->underlay_htaps;
-+ results->h_taps[2] = mode_data->underlay_htaps;
-+ results->h_taps[3] = mode_data->underlay_htaps;
-+ results->v_taps[0] = mode_data->underlay_vtaps;
-+ results->v_taps[1] = mode_data->underlay_vtaps;
-+ results->v_taps[2] = mode_data->underlay_vtaps;
-+ results->v_taps[3] = mode_data->underlay_vtaps;
-+ results->rotation_angle[0] = mode_data->underlay_rotation_angle;
-+ results->rotation_angle[1] = mode_data->underlay_rotation_angle;
-+ results->rotation_angle[2] = mode_data->underlay_rotation_angle;
-+ results->rotation_angle[3] = mode_data->underlay_rotation_angle;
-+ if (mode_data->underlay_tiling_mode == linear) {
-+ tiling_mode[0] = def_linear;
-+ tiling_mode[1] = def_linear;
-+ tiling_mode[2] = def_linear;
-+ tiling_mode[3] = def_linear;
-+ } else {
-+ tiling_mode[0] = def_landscape;
-+ tiling_mode[1] = def_landscape;
-+ tiling_mode[2] = def_landscape;
-+ tiling_mode[3] = def_landscape;
-+ }
-+ stereo_mode[0] = mode_data->underlay_stereo_mode;
-+ stereo_mode[1] = mode_data->underlay_stereo_mode;
-+ stereo_mode[2] = mode_data->underlay_stereo_mode;
-+ stereo_mode[3] = mode_data->underlay_stereo_mode;
-+ results->lb_bpc[0] = mode_data->underlay_lb_bpc;
-+ results->lb_bpc[1] = mode_data->underlay_lb_bpc;
-+ results->lb_bpc[2] = mode_data->underlay_lb_bpc;
-+ results->lb_bpc[3] = mode_data->underlay_lb_bpc;
-+ results->compression_rate[0] = int_to_fixed(1);
-+ results->compression_rate[1] = int_to_fixed(1);
-+ results->compression_rate[2] = int_to_fixed(1);
-+ results->compression_rate[3] = int_to_fixed(1);
-+ results->access_one_channel_only[0] = false;
-+ results->access_one_channel_only[1] = false;
-+ results->access_one_channel_only[2] = false;
-+ results->access_one_channel_only[3] = false;
-+ results->cursor_width_pixels[0] = int_to_fixed(0);
-+ results->cursor_width_pixels[1] = int_to_fixed(0);
-+ results->cursor_width_pixels[2] = int_to_fixed(0);
-+ results->cursor_width_pixels[3] = int_to_fixed(0);
-+ for (i = 4; i <= maximum_number_of_surfaces - 3; i += 1) {
-+ if (i < mode_data->number_of_displays + 4) {
-+ if (i == 4 && mode_data->d0_underlay_mode == ul_only) {
-+ results->enable[i] = false;
-+ results->use_alpha[i] = false;
-+ } else if (i == 4
-+ && mode_data->d0_underlay_mode == ul_blend) {
-+ results->enable[i] = true;
-+ results->use_alpha[i] = true;
-+ } else if (i == 4) {
-+ results->enable[i] = true;
-+ results->use_alpha[i] = false;
-+ } else if (i == 5
-+ && mode_data->d1_underlay_mode == ul_only) {
-+ results->enable[i] = false;
-+ results->use_alpha[i] = false;
-+ } else if (i == 5
-+ && mode_data->d1_underlay_mode == ul_blend) {
-+ results->enable[i] = true;
-+ results->use_alpha[i] = true;
-+ } else {
-+ results->enable[i] = true;
-+ results->use_alpha[i] = false;
-+ }
-+ } else {
-+ results->enable[i] = false;
-+ results->use_alpha[i] = false;
-+ }
-+ results->scatter_gather_enable_for_pipe[i] =
-+ vbios->scatter_gather_enable;
-+ surface_type[i] = def_graphics;
-+ results->lb_size_per_component[i] =
-+ dceip->lb_size_per_component444;
-+ results->bytes_per_pixel[i] =
-+ mode_data->graphics_bytes_per_pixel;
-+ results->interlace_mode[i] = mode_data->graphics_interlace_mode;
-+ results->h_taps[i] = mode_data->graphics_htaps;
-+ results->v_taps[i] = mode_data->graphics_vtaps;
-+ results->rotation_angle[i] = mode_data->graphics_rotation_angle;
-+ if (mode_data->graphics_tiling_mode == linear) {
-+ tiling_mode[i] = def_linear;
-+ } else if (equ(mode_data->graphics_rotation_angle,
-+ int_to_fixed(0))
-+ || equ(mode_data->graphics_rotation_angle,
-+ int_to_fixed(180))) {
-+ tiling_mode[i] = def_landscape;
-+ } else {
-+ tiling_mode[i] = def_portrait;
-+ }
-+ results->lb_bpc[i] = mode_data->graphics_lb_bpc;
-+ if (i == 4) {
-+ /* todo: check original d0_underlay_mode comparison, possible bug there*/
-+ if (mode_data->d0_fbc_enable
-+ && (dceip->argb_compression_support
-+ || mode_data->d0_underlay_mode
-+ != ul_blend)) {
-+ results->compression_rate[i] =
-+ vbios->average_compression_rate;
-+ results->access_one_channel_only[i] =
-+ mode_data->d0_lpt_enable;
-+ } else {
-+ results->compression_rate[i] = int_to_fixed(1);
-+ results->access_one_channel_only[i] = false;
-+ }
-+ results->h_total[i] = mode_data->d0_htotal;
-+ results->pixel_rate[i] = mode_data->d0_pixel_rate;
-+ results->src_width[i] =
-+ mode_data->d0_graphics_src_width;
-+ results->src_height[i] =
-+ mode_data->d0_graphics_src_height;
-+ results->pitch_in_pixels[i] =
-+ mode_data->d0_graphics_src_width;
-+ results->scale_ratio[i] =
-+ mode_data->d0_graphics_scale_ratio;
-+ stereo_mode[i] = mode_data->d0_graphics_stereo_mode;
-+ } else if (i == 5) {
-+ results->compression_rate[i] = int_to_fixed(1);
-+ results->access_one_channel_only[i] = false;
-+ results->h_total[i] = mode_data->d1_htotal;
-+ results->pixel_rate[i] = mode_data->d1_pixel_rate;
-+ results->src_width[i] =
-+ mode_data->d1_graphics_src_width;
-+ results->src_height[i] =
-+ mode_data->d1_graphics_src_height;
-+ results->pitch_in_pixels[i] =
-+ mode_data->d1_graphics_src_width;
-+ results->scale_ratio[i] =
-+ mode_data->d1_graphics_scale_ratio;
-+ stereo_mode[i] = mode_data->d1_graphics_stereo_mode;
-+ } else {
-+ results->compression_rate[i] = int_to_fixed(1);
-+ results->access_one_channel_only[i] = false;
-+ results->h_total[i] = mode_data->d2_htotal;
-+ results->pixel_rate[i] = mode_data->d2_pixel_rate;
-+ results->src_width[i] =
-+ mode_data->d2_graphics_src_width;
-+ results->src_height[i] =
-+ mode_data->d2_graphics_src_height;
-+ results->pitch_in_pixels[i] =
-+ mode_data->d2_graphics_src_width;
-+ results->scale_ratio[i] =
-+ mode_data->d2_graphics_scale_ratio;
-+ stereo_mode[i] = mode_data->d2_graphics_stereo_mode;
-+ }
-+ results->cursor_width_pixels[i] = vbios->cursor_width;
-+ }
-+ results->scatter_gather_enable_for_pipe[maximum_number_of_surfaces - 2] =
-+ false;
-+ results->scatter_gather_enable_for_pipe[maximum_number_of_surfaces - 1] =
-+ false;
-+ if (mode_data->d1_display_write_back_dwb_enable == true) {
-+ results->enable[maximum_number_of_surfaces - 2] = true;
-+ results->enable[maximum_number_of_surfaces - 1] = true;
-+ } else {
-+ results->enable[maximum_number_of_surfaces - 2] = false;
-+ results->enable[maximum_number_of_surfaces - 1] = false;
-+ }
-+ surface_type[maximum_number_of_surfaces - 2] =
-+ def_display_write_back420_luma;
-+ surface_type[maximum_number_of_surfaces - 1] =
-+ def_display_write_back420_chroma;
-+ results->lb_size_per_component[maximum_number_of_surfaces - 2] =
-+ dceip->underlay420_luma_lb_size_per_component;
-+ results->lb_size_per_component[maximum_number_of_surfaces - 1] =
-+ dceip->underlay420_chroma_lb_size_per_component;
-+ results->bytes_per_pixel[maximum_number_of_surfaces - 2] = int_to_fixed(
-+ 1);
-+ results->bytes_per_pixel[maximum_number_of_surfaces - 1] = int_to_fixed(
-+ 2);
-+ results->interlace_mode[maximum_number_of_surfaces - 2] =
-+ mode_data->graphics_interlace_mode;
-+ results->interlace_mode[maximum_number_of_surfaces - 1] =
-+ mode_data->graphics_interlace_mode;
-+ results->h_taps[maximum_number_of_surfaces - 2] = int_to_fixed(1);
-+ results->h_taps[maximum_number_of_surfaces - 1] = int_to_fixed(1);
-+ results->v_taps[maximum_number_of_surfaces - 2] = int_to_fixed(1);
-+ results->v_taps[maximum_number_of_surfaces - 1] = int_to_fixed(1);
-+ results->rotation_angle[maximum_number_of_surfaces - 2] = int_to_fixed(
-+ 0);
-+ results->rotation_angle[maximum_number_of_surfaces - 1] = int_to_fixed(
-+ 0);
-+ tiling_mode[maximum_number_of_surfaces - 2] = def_linear;
-+ tiling_mode[maximum_number_of_surfaces - 1] = def_linear;
-+ results->lb_bpc[maximum_number_of_surfaces - 2] = int_to_fixed(8);
-+ results->lb_bpc[maximum_number_of_surfaces - 1] = int_to_fixed(8);
-+ results->compression_rate[maximum_number_of_surfaces - 2] =
-+ int_to_fixed(1);
-+ results->compression_rate[maximum_number_of_surfaces - 1] =
-+ int_to_fixed(1);
-+ results->access_one_channel_only[maximum_number_of_surfaces - 2] =
-+ false;
-+ results->access_one_channel_only[maximum_number_of_surfaces - 1] =
-+ false;
-+ results->h_total[maximum_number_of_surfaces - 2] = mode_data->d1_htotal;
-+ results->h_total[maximum_number_of_surfaces - 1] = mode_data->d1_htotal;
-+ results->pixel_rate[maximum_number_of_surfaces - 2] =
-+ mode_data->d1_pixel_rate;
-+ results->pixel_rate[maximum_number_of_surfaces - 1] =
-+ mode_data->d1_pixel_rate;
-+ results->src_width[maximum_number_of_surfaces - 2] =
-+ mode_data->d1_graphics_src_width;
-+ results->src_width[maximum_number_of_surfaces - 1] =
-+ mode_data->d1_graphics_src_width;
-+ results->src_height[maximum_number_of_surfaces - 2] =
-+ mode_data->d1_graphics_src_height;
-+ results->src_height[maximum_number_of_surfaces - 1] =
-+ mode_data->d1_graphics_src_height;
-+ results->pitch_in_pixels[maximum_number_of_surfaces - 2] =
-+ mode_data->d1_graphics_src_width;
-+ results->pitch_in_pixels[maximum_number_of_surfaces - 1] =
-+ mode_data->d1_graphics_src_width;
-+ results->scale_ratio[maximum_number_of_surfaces - 2] = int_to_fixed(1);
-+ results->scale_ratio[maximum_number_of_surfaces - 1] = int_to_fixed(1);
-+ stereo_mode[maximum_number_of_surfaces - 2] = mono;
-+ stereo_mode[maximum_number_of_surfaces - 1] = mono;
-+ results->cursor_width_pixels[maximum_number_of_surfaces - 2] =
-+ int_to_fixed(0);
-+ results->cursor_width_pixels[maximum_number_of_surfaces - 1] =
-+ int_to_fixed(0);
-+ results->use_alpha[maximum_number_of_surfaces - 2] = false;
-+ results->use_alpha[maximum_number_of_surfaces - 1] = false;
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (equ(results->scale_ratio[i], int_to_fixed(1))
-+ && surface_type[i] == def_graphics
-+ && stereo_mode[i] == mono
-+ && results->interlace_mode[i] == false) {
-+ results->h_taps[i] = int_to_fixed(1);
-+ results->v_taps[i] = int_to_fixed(1);
-+ }
-+ if (surface_type[i] == def_display_write_back420_chroma
-+ || surface_type[i] == def_underlay420_chroma) {
-+ results->pitch_in_pixels_after_surface_type[i] =
-+ bw_div(results->pitch_in_pixels[i],
-+ int_to_fixed(2));
-+ results->src_width_after_surface_type = bw_div(
-+ results->src_width[i], int_to_fixed(2));
-+ results->src_height_after_surface_type = bw_div(
-+ results->src_height[i],
-+ int_to_fixed(2));
-+ results->hsr_after_surface_type = bw_div(
-+ results->scale_ratio[i],
-+ int_to_fixed(2));
-+ results->vsr_after_surface_type = bw_div(
-+ results->scale_ratio[i],
-+ int_to_fixed(2));
-+ } else {
-+ results->pitch_in_pixels_after_surface_type[i] =
-+ results->pitch_in_pixels[i];
-+ results->src_width_after_surface_type =
-+ results->src_width[i];
-+ results->src_height_after_surface_type =
-+ results->src_height[i];
-+ results->hsr_after_surface_type =
-+ results->scale_ratio[i];
-+ results->vsr_after_surface_type =
-+ results->scale_ratio[i];
-+ }
-+ if ((equ(results->rotation_angle[i], int_to_fixed(90))
-+ || equ(results->rotation_angle[i],
-+ int_to_fixed(270)))
-+ && surface_type[i] != def_graphics) {
-+ results->src_width_after_rotation =
-+ results->src_height_after_surface_type;
-+ results->src_height_after_rotation =
-+ results->src_width_after_surface_type;
-+ results->hsr_after_rotation =
-+ results->vsr_after_surface_type;
-+ results->vsr_after_rotation =
-+ results->hsr_after_surface_type;
-+ } else {
-+ results->src_width_after_rotation =
-+ results->src_width_after_surface_type;
-+ results->src_height_after_rotation =
-+ results->src_height_after_surface_type;
-+ results->hsr_after_rotation =
-+ results->hsr_after_surface_type;
-+ results->vsr_after_rotation =
-+ results->vsr_after_surface_type;
-+ }
-+ if (stereo_mode[i] == top_bottom) {
-+ results->source_width_pixels[i] =
-+ results->src_width_after_rotation;
-+ results->source_height_pixels = mul(
-+ int_to_fixed(2),
-+ results->src_height_after_rotation);
-+ results->hsr_after_stereo =
-+ results->hsr_after_rotation;
-+ results->vsr_after_stereo = mul(
-+ results->vsr_after_rotation,
-+ int_to_fixed(1)); //todo: confirm correctness
-+ } else if (stereo_mode[i] == side_by_side) {
-+ results->source_width_pixels[i] = mul(
-+ int_to_fixed(2),
-+ results->src_width_after_rotation);
-+ results->source_height_pixels =
-+ results->src_height_after_rotation;
-+ results->hsr_after_stereo = mul(
-+ results->hsr_after_rotation,
-+ int_to_fixed(1)); //todo: confirm correctness
-+ results->vsr_after_stereo =
-+ results->vsr_after_rotation;
-+ } else {
-+ results->source_width_pixels[i] =
-+ results->src_width_after_rotation;
-+ results->source_height_pixels =
-+ results->src_height_after_rotation;
-+ results->hsr_after_stereo =
-+ results->hsr_after_rotation;
-+ results->vsr_after_stereo =
-+ results->vsr_after_rotation;
-+ }
-+ results->hsr[i] = results->hsr_after_stereo;
-+ if (results->interlace_mode[i]) {
-+ results->vsr[i] = mul(results->vsr_after_stereo,
-+ int_to_fixed(2));
-+ } else {
-+ results->vsr[i] = results->vsr_after_stereo;
-+ }
-+ if (mode_data->panning_and_bezel_adjustment != none) {
-+ results->source_width_rounded_up_to_chunks[i] =
-+ add(
-+ bw_floor(
-+ sub(
-+ results->source_width_pixels[i],
-+ int_to_fixed(
-+ 1)),
-+ int_to_fixed(128)),
-+ int_to_fixed(256));
-+ } else {
-+ results->source_width_rounded_up_to_chunks[i] =
-+ bw_ceil(results->source_width_pixels[i],
-+ int_to_fixed(128));
-+ }
-+ results->source_height_rounded_up_to_chunks[i] =
-+ results->source_height_pixels;
-+ }
-+ }
-+ if (geq(dceip->number_of_graphics_pipes,
-+ int_to_fixed(mode_data->number_of_displays))
-+ && geq(dceip->number_of_underlay_pipes,
-+ results->number_of_underlay_surfaces)
-+ && !(dceip->display_write_back_supported == false
-+ && mode_data->d1_display_write_back_dwb_enable == true)) {
-+ pipe_check = def_ok;
-+ } else {
-+ pipe_check = def_notok;
-+ }
-+ hsr_check = def_ok;
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (neq(results->hsr[i], int_to_fixed(1))) {
-+ if (gtn(results->hsr[i], int_to_fixed(4))) {
-+ hsr_check = def_hsr_more_than_4;
-+ } else {
-+ if (gtn(results->hsr[i],
-+ results->h_taps[i])) {
-+ hsr_check =
-+ def_hsr_more_than_htaps;
-+ } else {
-+ if (dceip->pre_downscaler_enabled
-+ == true
-+ && gtn(results->hsr[i],
-+ int_to_fixed(1))
-+ && leq(results->hsr[i],
-+ bw_ceil(
-+ bw_div(
-+ results->h_taps[i],
-+ int_to_fixed(
-+ 4)),
-+ int_to_fixed(
-+ 1)))) {
-+ hsr_check =
-+ def_ceil_htaps_div_4_more_or_eq_hsr;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+ vsr_check = def_ok;
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (neq(results->vsr[i], int_to_fixed(1))) {
-+ if (gtn(results->vsr[i], int_to_fixed(4))) {
-+ vsr_check = def_vsr_more_than_4;
-+ } else {
-+ if (gtn(results->vsr[i],
-+ results->v_taps[i])) {
-+ vsr_check =
-+ def_vsr_more_than_vtaps;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ lb_size_check = def_ok;
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if ((dceip->pre_downscaler_enabled
-+ && gtn(results->hsr[i], int_to_fixed(1)))) {
-+ results->source_width_in_lb = bw_div(
-+ results->source_width_pixels[i],
-+ results->hsr[i]);
-+ } else {
-+ results->source_width_in_lb =
-+ results->source_width_pixels[i];
-+ }
-+ if (equ(results->lb_bpc[i], int_to_fixed(8))) {
-+ results->lb_line_pitch =
-+ bw_ceil(
-+ mul(frc_to_fixed(24011, 3000),
-+ bw_ceil(
-+ results->source_width_in_lb,
-+ int_to_fixed(
-+ 8))),
-+ int_to_fixed(48));
-+ } else if (equ(results->lb_bpc[i], int_to_fixed(10))) {
-+ results->lb_line_pitch =
-+ bw_ceil(
-+ mul(frc_to_fixed(30023, 3000),
-+ bw_ceil(
-+ results->source_width_in_lb,
-+ int_to_fixed(
-+ 8))),
-+ int_to_fixed(48));
-+ } else
-+ // case else
-+ {
-+ results->lb_line_pitch = bw_ceil(
-+ mul(results->source_width_in_lb,
-+ results->lb_bpc[i]),
-+ int_to_fixed(48));
-+ }
-+ results->lb_partitions[i] = bw_floor(
-+ bw_div(results->lb_size_per_component[i],
-+ results->lb_line_pitch),
-+ int_to_fixed(1));
-+ if ((surface_type[i] != def_graphics
-+ || dceip->graphics_lb_nodownscaling_multi_line_prefetching
-+ == true)) {
-+ results->lb_partitions_max[i] = int_to_fixed(
-+ 10);
-+ } else {
-+ results->lb_partitions_max[i] = int_to_fixed(7);
-+ }
-+ results->lb_partitions[i] = bw_min(
-+ results->lb_partitions_max[i],
-+ results->lb_partitions[i]);
-+ if (gtn(add(results->v_taps[i], int_to_fixed(1)),
-+ results->lb_partitions[i])) {
-+ lb_size_check = def_notok;
-+ }
-+ }
-+ }
-+ if (mode_data->d0_fbc_enable
-+ && (equ(mode_data->graphics_rotation_angle, int_to_fixed(90))
-+ || equ(mode_data->graphics_rotation_angle,
-+ int_to_fixed(270))
-+ || mode_data->d0_graphics_stereo_mode != mono
-+ || neq(mode_data->graphics_bytes_per_pixel,
-+ int_to_fixed(4)))) {
-+ fbc_check = def_invalid_rotation_or_bpp_or_stereo;
-+ } else {
-+ fbc_check = def_ok;
-+ }
-+ rotation_check = def_ok;
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if ((equ(results->rotation_angle[i], int_to_fixed(90))
-+ || equ(results->rotation_angle[i],
-+ int_to_fixed(270)))
-+ && (tiling_mode[i] == def_linear
-+ || stereo_mode[i] != mono)) {
-+ rotation_check =
-+ def_invalid_linear_or_stereo_mode;
-+ }
-+ }
-+ }
-+ if (pipe_check == def_ok && hsr_check == def_ok && vsr_check == def_ok
-+ && lb_size_check == def_ok && fbc_check == def_ok
-+ && rotation_check == def_ok) {
-+ mode_check = def_ok;
-+ } else {
-+ mode_check = def_notok;
-+ }
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if ((equ(results->rotation_angle[i], int_to_fixed(90))
-+ || equ(results->rotation_angle[i],
-+ int_to_fixed(270)))) {
-+ if ((tiling_mode[i] == def_portrait)) {
-+ results->orthogonal_rotation[i] = false;
-+ } else {
-+ results->orthogonal_rotation[i] = true;
-+ }
-+ } else {
-+ if ((tiling_mode[i] == def_portrait)) {
-+ results->orthogonal_rotation[i] = true;
-+ } else {
-+ results->orthogonal_rotation[i] = false;
-+ }
-+ }
-+ if (equ(results->rotation_angle[i], int_to_fixed(90))
-+ || equ(results->rotation_angle[i],
-+ int_to_fixed(270))) {
-+ results->underlay_maximum_source_efficient_for_tiling =
-+ dceip->underlay_maximum_height_efficient_for_tiling;
-+ } else {
-+ results->underlay_maximum_source_efficient_for_tiling =
-+ dceip->underlay_maximum_width_efficient_for_tiling;
-+ }
-+ if (equ(dceip->de_tiling_buffer, int_to_fixed(0))) {
-+ if (surface_type[i]
-+ == def_display_write_back420_luma
-+ || surface_type[i]
-+ == def_display_write_back420_chroma) {
-+ results->bytes_per_request[i] =
-+ int_to_fixed(64);
-+ results->useful_bytes_per_request[i] =
-+ int_to_fixed(64);
-+ results->lines_interleaved_in_mem_access[i] =
-+ int_to_fixed(1);
-+ results->latency_hiding_lines[i] =
-+ int_to_fixed(1);
-+ } else if (tiling_mode[i] == def_linear) {
-+ results->bytes_per_request[i] =
-+ int_to_fixed(64);
-+ results->useful_bytes_per_request[i] =
-+ int_to_fixed(64);
-+ results->lines_interleaved_in_mem_access[i] =
-+ int_to_fixed(2);
-+ results->latency_hiding_lines[i] =
-+ int_to_fixed(2);
-+ } else {
-+ if (surface_type[i] == def_graphics
-+ || (gtn(
-+ results->source_width_rounded_up_to_chunks[i],
-+ bw_ceil(
-+ results->underlay_maximum_source_efficient_for_tiling,
-+ int_to_fixed(
-+ 256))))) {
-+ if (equ(
-+ results->bytes_per_pixel[i],
-+ int_to_fixed(8))) {
-+ results->lines_interleaved_in_mem_access[i] =
-+ int_to_fixed(2);
-+ results->latency_hiding_lines[i] =
-+ int_to_fixed(2);
-+ if (results->orthogonal_rotation[i]) {
-+ results->bytes_per_request[i] =
-+ int_to_fixed(
-+ 32);
-+ results->useful_bytes_per_request[i] =
-+ int_to_fixed(
-+ 32);
-+ } else {
-+ results->bytes_per_request[i] =
-+ int_to_fixed(
-+ 64);
-+ results->useful_bytes_per_request[i] =
-+ int_to_fixed(
-+ 64);
-+ }
-+ } else if (equ(
-+ results->bytes_per_pixel[i],
-+ int_to_fixed(4))) {
-+ if (results->orthogonal_rotation[i]) {
-+ results->lines_interleaved_in_mem_access[i] =
-+ int_to_fixed(
-+ 2);
-+ results->latency_hiding_lines[i] =
-+ int_to_fixed(
-+ 2);
-+ results->bytes_per_request[i] =
-+ int_to_fixed(
-+ 32);
-+ results->useful_bytes_per_request[i] =
-+ int_to_fixed(
-+ 16);
-+ } else {
-+ results->lines_interleaved_in_mem_access[i] =
-+ int_to_fixed(
-+ 2);
-+ results->latency_hiding_lines[i] =
-+ int_to_fixed(
-+ 2);
-+ results->bytes_per_request[i] =
-+ int_to_fixed(
-+ 64);
-+ results->useful_bytes_per_request[i] =
-+ int_to_fixed(
-+ 64);
-+ }
-+ } else if (equ(
-+ results->bytes_per_pixel[i],
-+ int_to_fixed(2))) {
-+ results->lines_interleaved_in_mem_access[i] =
-+ int_to_fixed(2);
-+ results->latency_hiding_lines[i] =
-+ int_to_fixed(2);
-+ results->bytes_per_request[i] =
-+ int_to_fixed(
-+ 32);
-+ results->useful_bytes_per_request[i] =
-+ int_to_fixed(
-+ 32);
-+ } else {
-+ results->lines_interleaved_in_mem_access[i] =
-+ int_to_fixed(2);
-+ results->latency_hiding_lines[i] =
-+ int_to_fixed(2);
-+ results->bytes_per_request[i] =
-+ int_to_fixed(
-+ 32);
-+ results->useful_bytes_per_request[i] =
-+ int_to_fixed(
-+ 16);
-+ }
-+ } else {
-+ results->bytes_per_request[i] =
-+ int_to_fixed(64);
-+ results->useful_bytes_per_request[i] =
-+ int_to_fixed(64);
-+ if (results->orthogonal_rotation[i]) {
-+ results->lines_interleaved_in_mem_access[i] =
-+ int_to_fixed(8);
-+ results->latency_hiding_lines[i] =
-+ int_to_fixed(4);
-+ } else {
-+ if (equ(
-+ results->bytes_per_pixel[i],
-+ int_to_fixed(
-+ 4))) {
-+ results->lines_interleaved_in_mem_access[i] =
-+ int_to_fixed(
-+ 2);
-+ results->latency_hiding_lines[i] =
-+ int_to_fixed(
-+ 2);
-+ } else if (equ(
-+ results->bytes_per_pixel[i],
-+ int_to_fixed(
-+ 2))) {
-+ results->lines_interleaved_in_mem_access[i] =
-+ int_to_fixed(
-+ 4);
-+ results->latency_hiding_lines[i] =
-+ int_to_fixed(
-+ 4);
-+ } else {
-+ results->lines_interleaved_in_mem_access[i] =
-+ int_to_fixed(
-+ 8);
-+ results->latency_hiding_lines[i] =
-+ int_to_fixed(
-+ 4);
-+ }
-+ }
-+ }
-+ }
-+ } else {
-+ results->bytes_per_request[i] = int_to_fixed(
-+ 256);
-+ results->useful_bytes_per_request[i] =
-+ int_to_fixed(256);
-+ results->lines_interleaved_in_mem_access[i] =
-+ int_to_fixed(4);
-+ results->latency_hiding_lines[i] = int_to_fixed(
-+ 4);
-+ }
-+ }
-+ }
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ results->v_filter_init[i] =
-+ bw_floor(
-+ bw_div(
-+ (add(
-+ add(
-+ add(
-+ results->vsr[i],
-+ results->v_taps[i]),
-+ mul(
-+ mul(
-+ frc_to_fixed(
-+ 1,
-+ 2),
-+ results->vsr[i]),
-+ int_to_fixed(
-+ results->interlace_mode[i]))),
-+ int_to_fixed(1))),
-+ int_to_fixed(2)),
-+ int_to_fixed(1));
-+ if (mode_data->panning_and_bezel_adjustment
-+ == any_lines) {
-+ results->v_filter_init[i] = add(
-+ results->v_filter_init[i],
-+ int_to_fixed(1));
-+ }
-+ if (stereo_mode[i] == top_bottom) {
-+ v_filter_init_mode[i] = def_manual;
-+ results->v_filter_init[i] = bw_min(
-+ results->v_filter_init[i],
-+ int_to_fixed(4));
-+ } else {
-+ v_filter_init_mode[i] = def_auto;
-+ }
-+ if (stereo_mode[i] == top_bottom) {
-+ results->num_lines_at_frame_start =
-+ int_to_fixed(1);
-+ } else {
-+ results->num_lines_at_frame_start =
-+ int_to_fixed(3);
-+ }
-+ if ((gtn(results->vsr[i], int_to_fixed(1))
-+ && surface_type[i] == def_graphics)
-+ || mode_data->panning_and_bezel_adjustment
-+ == any_lines) {
-+ results->line_buffer_prefetch[i] = int_to_fixed(
-+ 0);
-+ } else if ((((dceip->underlay_downscale_prefetch_enabled
-+ == true && surface_type[i] != def_graphics)
-+ || surface_type[i] == def_graphics)
-+ && (gtn(results->lb_partitions[i],
-+ add(results->v_taps[i],
-+ bw_ceil(results->vsr[i],
-+ int_to_fixed(1))))))) {
-+ results->line_buffer_prefetch[i] = int_to_fixed(
-+ 1);
-+ } else {
-+ results->line_buffer_prefetch[i] = int_to_fixed(
-+ 0);
-+ }
-+ results->lb_lines_in_per_line_out_in_beginning_of_frame[i] =
-+ bw_div(
-+ bw_ceil(results->v_filter_init[i],
-+ dceip->lines_interleaved_into_lb),
-+ results->num_lines_at_frame_start);
-+ if (equ(results->line_buffer_prefetch[i],
-+ int_to_fixed(1))) {
-+ results->lb_lines_in_per_line_out_in_middle_of_frame[i] =
-+ bw_max(int_to_fixed(1),
-+ results->vsr[i]);
-+ } else if (leq(results->vsr[i], int_to_fixed(1))) {
-+ results->lb_lines_in_per_line_out_in_middle_of_frame[i] =
-+ int_to_fixed(1);
-+ } else if (leq(results->vsr[i],
-+ bw_div(int_to_fixed(4), int_to_fixed(3)))) {
-+ results->lb_lines_in_per_line_out_in_middle_of_frame[i] =
-+ bw_div(int_to_fixed(4), int_to_fixed(3));
-+ } else if (leq(results->vsr[i],
-+ bw_div(int_to_fixed(6), int_to_fixed(4)))) {
-+ results->lb_lines_in_per_line_out_in_middle_of_frame[i] =
-+ bw_div(int_to_fixed(6), int_to_fixed(4));
-+ } else if (leq(results->vsr[i], int_to_fixed(2))) {
-+ results->lb_lines_in_per_line_out_in_middle_of_frame[i] =
-+ int_to_fixed(2);
-+ } else if (leq(results->vsr[i], int_to_fixed(3))) {
-+ results->lb_lines_in_per_line_out_in_middle_of_frame[i] =
-+ int_to_fixed(3);
-+ } else {
-+ results->lb_lines_in_per_line_out_in_middle_of_frame[i] =
-+ int_to_fixed(4);
-+ }
-+ if (equ(results->line_buffer_prefetch[i],
-+ int_to_fixed(1))
-+ || equ(
-+ results->lb_lines_in_per_line_out_in_middle_of_frame[i],
-+ int_to_fixed(2))
-+ || equ(
-+ results->lb_lines_in_per_line_out_in_middle_of_frame[i],
-+ int_to_fixed(4))) {
-+ results->horizontal_blank_and_chunk_granularity_factor[i] =
-+ int_to_fixed(1);
-+ } else {
-+ results->horizontal_blank_and_chunk_granularity_factor[i] =
-+ bw_div(results->h_total[i],
-+ (bw_div(
-+ (add(
-+ results->h_total[i],
-+ bw_div(
-+ (sub(
-+ results->source_width_pixels[i],
-+ dceip->chunk_width)),
-+ results->hsr[i]))),
-+ int_to_fixed(2))));
-+ }
-+ results->request_bandwidth[i] =
-+ bw_div(
-+ mul(
-+ bw_div(
-+ mul(
-+ bw_div(
-+ mul(
-+ bw_max(
-+ results->lb_lines_in_per_line_out_in_beginning_of_frame[i],
-+ results->lb_lines_in_per_line_out_in_middle_of_frame[i]),
-+ results->source_width_rounded_up_to_chunks[i]),
-+ (bw_div(
-+ results->h_total[i],
-+ results->pixel_rate[i]))),
-+ results->bytes_per_pixel[i]),
-+ results->useful_bytes_per_request[i]),
-+ results->lines_interleaved_in_mem_access[i]),
-+ results->latency_hiding_lines[i]);
-+ results->display_bandwidth[i] = mul(
-+ results->request_bandwidth[i],
-+ results->bytes_per_request[i]);
-+ }
-+ }
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (surface_type[i] == def_display_write_back420_luma) {
-+ results->data_buffer_size[i] =
-+ dceip->display_write_back420_luma_mcifwr_buffer_size;
-+ } else if (surface_type[i]
-+ == def_display_write_back420_chroma) {
-+ results->data_buffer_size[i] =
-+ dceip->display_write_back420_chroma_mcifwr_buffer_size;
-+ } else if (surface_type[i] == def_underlay420_luma) {
-+ results->data_buffer_size[i] =
-+ dceip->underlay_luma_dmif_size;
-+ } else if (surface_type[i] == def_underlay420_chroma) {
-+ results->data_buffer_size[i] = bw_div(
-+ dceip->underlay_chroma_dmif_size,
-+ int_to_fixed(2));
-+ } else if (surface_type[i] == def_underlay422
-+ || surface_type[i] == def_underlay444) {
-+ if (results->orthogonal_rotation[i] == false) {
-+ results->data_buffer_size[i] =
-+ dceip->underlay_luma_dmif_size;
-+ } else {
-+ results->data_buffer_size[i] =
-+ add(
-+ dceip->underlay_luma_dmif_size,
-+ dceip->underlay_chroma_dmif_size);
-+ }
-+ } else {
-+ if (mode_data->number_of_displays == 1
-+ && equ(dceip->de_tiling_buffer,
-+ int_to_fixed(0))) {
-+ if (mode_data->d0_fbc_enable) {
-+ results->data_buffer_size[i] =
-+ mul(
-+ dceip->max_dmif_buffer_allocated,
-+ dceip->graphics_dmif_size);
-+ } else {
-+ results->data_buffer_size[i] =
-+ mul(
-+ mul(
-+ max_chunks_non_fbc_mode,
-+ pixels_per_chunk),
-+ results->bytes_per_pixel[i]);
-+ }
-+ } else {
-+ results->data_buffer_size[i] =
-+ dceip->graphics_dmif_size;
-+ }
-+ }
-+ if (surface_type[i] == def_display_write_back420_luma
-+ || surface_type[i]
-+ == def_display_write_back420_chroma) {
-+ results->memory_chunk_size_in_bytes[i] =
-+ int_to_fixed(1024);
-+ results->pipe_chunk_size_in_bytes[i] =
-+ int_to_fixed(1024);
-+ } else {
-+ results->memory_chunk_size_in_bytes[i] =
-+ mul(
-+ mul(dceip->chunk_width,
-+ results->lines_interleaved_in_mem_access[i]),
-+ results->bytes_per_pixel[i]);
-+ results->pipe_chunk_size_in_bytes[i] =
-+ mul(
-+ mul(dceip->chunk_width,
-+ dceip->lines_interleaved_into_lb),
-+ results->bytes_per_pixel[i]);
-+ }
-+ }
-+ }
-+ results->min_dmif_size_in_time = int_to_fixed(9999);
-+ results->min_mcifwr_size_in_time = int_to_fixed(9999);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (surface_type[i] != def_display_write_back420_luma
-+ && surface_type[i]
-+ != def_display_write_back420_chroma) {
-+ if (ltn(
-+ bw_div(
-+ bw_div(
-+ mul(
-+ results->data_buffer_size[i],
-+ results->bytes_per_request[i]),
-+ results->useful_bytes_per_request[i]),
-+ results->display_bandwidth[i]),
-+ results->min_dmif_size_in_time)) {
-+ results->min_dmif_size_in_time =
-+ bw_div(
-+ bw_div(
-+ mul(
-+ results->data_buffer_size[i],
-+ results->bytes_per_request[i]),
-+ results->useful_bytes_per_request[i]),
-+ results->display_bandwidth[i]);
-+ }
-+ } else {
-+ if (ltn(
-+ bw_div(
-+ bw_div(
-+ mul(
-+ results->data_buffer_size[i],
-+ results->bytes_per_request[i]),
-+ results->useful_bytes_per_request[i]),
-+ results->display_bandwidth[i]),
-+ results->min_mcifwr_size_in_time)) {
-+ results->min_mcifwr_size_in_time =
-+ bw_div(
-+ bw_div(
-+ mul(
-+ results->data_buffer_size[i],
-+ results->bytes_per_request[i]),
-+ results->useful_bytes_per_request[i]),
-+ results->display_bandwidth[i]);
-+ }
-+ }
-+ }
-+ }
-+ results->total_requests_for_dmif_size = int_to_fixed(0);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]
-+ && surface_type[i] != def_display_write_back420_luma
-+ && surface_type[i]
-+ != def_display_write_back420_chroma) {
-+ results->total_requests_for_dmif_size = add(
-+ results->total_requests_for_dmif_size,
-+ bw_div(results->data_buffer_size[i],
-+ results->useful_bytes_per_request[i]));
-+ }
-+ }
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (surface_type[i] != def_display_write_back420_luma
-+ && surface_type[i]
-+ != def_display_write_back420_chroma
-+ && dceip->limit_excessive_outstanding_dmif_requests
-+ && (mode_data->number_of_displays > 1
-+ || gtn(
-+ results->total_requests_for_dmif_size,
-+ dceip->dmif_request_buffer_size))) {
-+ results->adjusted_data_buffer_size[i] =
-+ bw_min(results->data_buffer_size[i],
-+ bw_ceil(
-+ mul(
-+ results->min_dmif_size_in_time,
-+ results->display_bandwidth[i]),
-+ results->memory_chunk_size_in_bytes[i]));
-+ } else {
-+ results->adjusted_data_buffer_size[i] =
-+ results->data_buffer_size[i];
-+ }
-+ }
-+ }
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if ((mode_data->number_of_displays == 1
-+ && equ(results->number_of_underlay_surfaces,
-+ int_to_fixed(0)))) {
-+ results->outstanding_chunk_request_limit[i] =
-+ int_to_fixed(255);
-+ } else {
-+ results->outstanding_chunk_request_limit[i] =
-+ bw_ceil(
-+ bw_div(
-+ results->adjusted_data_buffer_size[i],
-+ results->pipe_chunk_size_in_bytes[i]),
-+ int_to_fixed(1));
-+ }
-+ }
-+ }
-+ if (mode_data->number_of_displays > 1
-+ || (neq(mode_data->graphics_rotation_angle, int_to_fixed(0))
-+ && neq(mode_data->graphics_rotation_angle,
-+ int_to_fixed(180)))) {
-+ results->peak_pte_request_to_eviction_ratio_limiting =
-+ dceip->peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display;
-+ } else {
-+ results->peak_pte_request_to_eviction_ratio_limiting =
-+ dceip->peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation;
-+ }
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]
-+ && results->scatter_gather_enable_for_pipe[i] == true) {
-+ if (tiling_mode[i] == def_linear) {
-+ results->useful_pte_per_pte_request =
-+ int_to_fixed(8);
-+ results->scatter_gather_page_width[i] = bw_div(
-+ int_to_fixed(4096),
-+ results->bytes_per_pixel[i]);
-+ results->scatter_gather_page_height[i] =
-+ int_to_fixed(1);
-+ results->scatter_gather_pte_request_rows =
-+ int_to_fixed(1);
-+ results->scatter_gather_row_height =
-+ dceip->scatter_gather_lines_of_pte_prefetching_in_linear_mode;
-+ } else if (equ(results->rotation_angle[i],
-+ int_to_fixed(0))
-+ || equ(results->rotation_angle[i],
-+ int_to_fixed(180))) {
-+ results->useful_pte_per_pte_request =
-+ int_to_fixed(8);
-+ if (equ(results->bytes_per_pixel[i],
-+ int_to_fixed(4))) {
-+ results->scatter_gather_page_width[i] =
-+ int_to_fixed(32);
-+ results->scatter_gather_page_height[i] =
-+ int_to_fixed(32);
-+ } else if (equ(results->bytes_per_pixel[i],
-+ int_to_fixed(2))) {
-+ results->scatter_gather_page_width[i] =
-+ int_to_fixed(64);
-+ results->scatter_gather_page_height[i] =
-+ int_to_fixed(32);
-+ } else {
-+ results->scatter_gather_page_width[i] =
-+ int_to_fixed(64);
-+ results->scatter_gather_page_height[i] =
-+ int_to_fixed(64);
-+ }
-+ results->scatter_gather_pte_request_rows =
-+ dceip->scatter_gather_pte_request_rows_in_tiling_mode;
-+ results->scatter_gather_row_height =
-+ results->scatter_gather_page_height[i];
-+ } else {
-+ results->useful_pte_per_pte_request =
-+ int_to_fixed(1);
-+ if (equ(results->bytes_per_pixel[i],
-+ int_to_fixed(4))) {
-+ results->scatter_gather_page_width[i] =
-+ int_to_fixed(32);
-+ results->scatter_gather_page_height[i] =
-+ int_to_fixed(32);
-+ } else if (equ(results->bytes_per_pixel[i],
-+ int_to_fixed(2))) {
-+ results->scatter_gather_page_width[i] =
-+ int_to_fixed(32);
-+ results->scatter_gather_page_height[i] =
-+ int_to_fixed(64);
-+ } else
-+ // case else
-+ {
-+ results->scatter_gather_page_width[i] =
-+ int_to_fixed(64);
-+ results->scatter_gather_page_height[i] =
-+ int_to_fixed(64);
-+ }
-+ results->scatter_gather_pte_request_rows =
-+ dceip->scatter_gather_pte_request_rows_in_tiling_mode;
-+ results->scatter_gather_row_height =
-+ results->scatter_gather_page_height[i];
-+ }
-+ results->pte_request_per_chunk[i] = bw_div(
-+ bw_div(dceip->chunk_width,
-+ results->scatter_gather_page_width[i]),
-+ results->useful_pte_per_pte_request);
-+ results->scatter_gather_pte_requests_in_row[i] =
-+ bw_div(
-+ mul(results->scatter_gather_row_height,
-+ bw_ceil(
-+ mul(
-+ bw_div(
-+ results->source_width_rounded_up_to_chunks[i],
-+ dceip->chunk_width),
-+ results->pte_request_per_chunk[i]),
-+ int_to_fixed(1))),
-+ results->scatter_gather_page_height[i]);
-+ results->scatter_gather_pte_requests_in_vblank = mul(
-+ results->scatter_gather_pte_request_rows,
-+ results->scatter_gather_pte_requests_in_row[i]);
-+ if (equ(
-+ results->peak_pte_request_to_eviction_ratio_limiting,
-+ int_to_fixed(0))) {
-+ results->scatter_gather_pte_request_limit[i] =
-+ results->scatter_gather_pte_requests_in_vblank;
-+ } else {
-+ results->scatter_gather_pte_request_limit[i] =
-+ bw_max(
-+ dceip->minimum_outstanding_pte_request_limit,
-+ bw_min(
-+ results->scatter_gather_pte_requests_in_vblank,
-+ bw_ceil(
-+ mul(
-+ mul(
-+ bw_div(
-+ bw_ceil(
-+ results->adjusted_data_buffer_size[i],
-+ results->memory_chunk_size_in_bytes[i]),
-+ results->memory_chunk_size_in_bytes[i]),
-+ results->pte_request_per_chunk[i]),
-+ results->peak_pte_request_to_eviction_ratio_limiting),
-+ int_to_fixed(
-+ 1))));
-+ }
-+ }
-+ }
-+ results->inefficient_linear_pitch_in_bytes = mul(
-+ mul(vbios->number_of_dram_banks,
-+ vbios->number_of_dram_channels), int_to_fixed(256));
-+ if (mode_data->underlay_surface_type == yuv_420) {
-+ results->inefficient_underlay_pitch_in_pixels =
-+ results->inefficient_linear_pitch_in_bytes;
-+ } else if (mode_data->underlay_surface_type == yuv_422) {
-+ results->inefficient_underlay_pitch_in_pixels = bw_div(
-+ results->inefficient_linear_pitch_in_bytes,
-+ int_to_fixed(2));
-+ } else
-+ // case else
-+ {
-+ results->inefficient_underlay_pitch_in_pixels = bw_div(
-+ results->inefficient_linear_pitch_in_bytes,
-+ int_to_fixed(4));
-+ }
-+ if (mode_data->underlay_tiling_mode == linear
-+ && vbios->scatter_gather_enable == true
-+ && mode_data->underlay_pitch_in_pixels.value
-+ % results->inefficient_underlay_pitch_in_pixels.value
-+ == false) {
-+ results->minimum_underlay_pitch_padding_recommended_for_efficiency =
-+ int_to_fixed(256);
-+ } else {
-+ results->minimum_underlay_pitch_padding_recommended_for_efficiency =
-+ int_to_fixed(0);
-+ }
-+ results->cursor_total_data = int_to_fixed(0);
-+ results->cursor_total_request_groups = int_to_fixed(0);
-+ results->scatter_gather_total_pte_requests = int_to_fixed(0);
-+ results->scatter_gather_total_pte_request_groups = int_to_fixed(0);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ results->cursor_total_data = add(
-+ results->cursor_total_data,
-+ mul(results->cursor_width_pixels[i],
-+ int_to_fixed(8)));
-+ results->cursor_total_request_groups = add(
-+ results->cursor_total_request_groups,
-+ bw_ceil(
-+ bw_div(results->cursor_width_pixels[i],
-+ dceip->cursor_chunk_width),
-+ int_to_fixed(1)));
-+ if (results->scatter_gather_enable_for_pipe[i]) {
-+ results->scatter_gather_total_pte_requests =
-+ add(
-+ results->scatter_gather_total_pte_requests,
-+ results->scatter_gather_pte_request_limit[i]);
-+ results->scatter_gather_total_pte_request_groups =
-+ add(
-+ results->scatter_gather_total_pte_request_groups,
-+ bw_ceil(
-+ bw_div(
-+ results->scatter_gather_pte_request_limit[i],
-+ bw_ceil(
-+ results->pte_request_per_chunk[i],
-+ int_to_fixed(
-+ 1))),
-+ int_to_fixed(1)));
-+ }
-+ }
-+ }
-+ results->tile_width_in_pixels = int_to_fixed(8);
-+ results->dmif_total_number_of_data_request_page_close_open =
-+ int_to_fixed(0);
-+ results->mcifwr_total_number_of_data_request_page_close_open =
-+ int_to_fixed(0);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (results->scatter_gather_enable_for_pipe[i] == true
-+ && tiling_mode[i] != def_linear) {
-+ results->bytes_per_page_close_open =
-+ mul(
-+ results->lines_interleaved_in_mem_access[i],
-+ bw_max(
-+ mul(
-+ mul(
-+ mul(
-+ results->bytes_per_pixel[i],
-+ results->tile_width_in_pixels),
-+ vbios->number_of_dram_banks),
-+ vbios->number_of_dram_channels),
-+ mul(
-+ results->bytes_per_pixel[i],
-+ results->scatter_gather_page_width[i])));
-+ } else if (results->scatter_gather_enable_for_pipe[i]
-+ == true && tiling_mode[i] == def_linear
-+ && (mul(
-+ results->pitch_in_pixels_after_surface_type[i],
-+ results->bytes_per_pixel[i])).value
-+ % results->inefficient_linear_pitch_in_bytes.value
-+ == false) {
-+ results->bytes_per_page_close_open =
-+ dceip->linear_mode_line_request_alternation_slice;
-+ } else {
-+ results->bytes_per_page_close_open =
-+ results->memory_chunk_size_in_bytes[i];
-+ }
-+ if (surface_type[i] != def_display_write_back420_luma
-+ && surface_type[i]
-+ != def_display_write_back420_chroma) {
-+ results->dmif_total_number_of_data_request_page_close_open =
-+ add(
-+ results->dmif_total_number_of_data_request_page_close_open,
-+ bw_div(
-+ bw_ceil(
-+ results->adjusted_data_buffer_size[i],
-+ results->memory_chunk_size_in_bytes[i]),
-+ results->bytes_per_page_close_open));
-+ } else {
-+ results->mcifwr_total_number_of_data_request_page_close_open =
-+ add(
-+ results->mcifwr_total_number_of_data_request_page_close_open,
-+ bw_div(
-+ bw_ceil(
-+ results->adjusted_data_buffer_size[i],
-+ results->memory_chunk_size_in_bytes[i]),
-+ results->bytes_per_page_close_open));
-+ }
-+ }
-+ }
-+ results->dmif_total_page_close_open_time =
-+ bw_div(
-+ mul(
-+ (add(
-+ add(
-+ results->dmif_total_number_of_data_request_page_close_open,
-+ results->scatter_gather_total_pte_request_groups),
-+ results->cursor_total_request_groups)),
-+ vbios->trc), int_to_fixed(1000));
-+ results->mcifwr_total_page_close_open_time =
-+ bw_div(
-+ mul(
-+ results->mcifwr_total_number_of_data_request_page_close_open,
-+ vbios->trc), int_to_fixed(1000));
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ results->adjusted_data_buffer_size_in_memory[i] = bw_div(
-+ mul(results->adjusted_data_buffer_size[i],
-+ results->bytes_per_request[i]),
-+ results->useful_bytes_per_request[i]);
-+ }
-+ }
-+ results->total_requests_for_adjusted_dmif_size = int_to_fixed(0);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (surface_type[i] != def_display_write_back420_luma
-+ && surface_type[i]
-+ != def_display_write_back420_chroma) {
-+ results->total_requests_for_adjusted_dmif_size =
-+ add(
-+ results->total_requests_for_adjusted_dmif_size,
-+ bw_div(
-+ results->adjusted_data_buffer_size[i],
-+ results->useful_bytes_per_request[i]));
-+ }
-+ }
-+ }
-+ if (equ(dceip->dcfclk_request_generation, int_to_fixed(1))) {
-+ results->total_dmifmc_urgent_trips = int_to_fixed(1);
-+ } else {
-+ results->total_dmifmc_urgent_trips =
-+ bw_ceil(
-+ bw_div(
-+ results->total_requests_for_adjusted_dmif_size,
-+ (add(dceip->dmif_request_buffer_size,
-+ mul(
-+ vbios->number_of_request_slots_gmc_reserves_for_dmif_per_channel,
-+ vbios->number_of_dram_channels)))),
-+ int_to_fixed(1));
-+ }
-+ results->total_dmifmc_urgent_latency = mul(vbios->dmifmc_urgent_latency,
-+ results->total_dmifmc_urgent_trips);
-+ results->total_display_reads_required_data = int_to_fixed(0);
-+ results->total_display_reads_required_dram_access_data = int_to_fixed(
-+ 0);
-+ results->total_display_writes_required_data = int_to_fixed(0);
-+ results->total_display_writes_required_dram_access_data = int_to_fixed(
-+ 0);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (surface_type[i] != def_display_write_back420_luma
-+ && surface_type[i]
-+ != def_display_write_back420_chroma) {
-+ results->display_reads_required_data =
-+ results->adjusted_data_buffer_size_in_memory[i];
-+ results->display_reads_required_dram_access_data =
-+ mul(
-+ results->adjusted_data_buffer_size_in_memory[i],
-+ bw_ceil(
-+ bw_div(
-+ vbios->dram_channel_width_in_bits,
-+ results->bytes_per_request[i]),
-+ int_to_fixed(1)));
-+ if (results->access_one_channel_only[i]) {
-+ results->display_reads_required_dram_access_data =
-+ mul(
-+ results->display_reads_required_dram_access_data,
-+ vbios->number_of_dram_channels);
-+ }
-+ results->total_display_reads_required_data =
-+ add(
-+ results->total_display_reads_required_data,
-+ results->display_reads_required_data);
-+ results->total_display_reads_required_dram_access_data =
-+ add(
-+ results->total_display_reads_required_dram_access_data,
-+ results->display_reads_required_dram_access_data);
-+ } else {
-+ results->total_display_writes_required_data =
-+ add(
-+ results->total_display_writes_required_data,
-+ results->adjusted_data_buffer_size_in_memory[i]);
-+ results->total_display_writes_required_dram_access_data =
-+ add(
-+ results->total_display_writes_required_dram_access_data,
-+ mul(
-+ results->adjusted_data_buffer_size_in_memory[i],
-+ bw_ceil(
-+ bw_div(
-+ vbios->dram_channel_width_in_bits,
-+ results->bytes_per_request[i]),
-+ int_to_fixed(
-+ 1))));
-+ }
-+ }
-+ }
-+ results->total_display_reads_required_data = add(
-+ add(results->total_display_reads_required_data,
-+ results->cursor_total_data),
-+ mul(results->scatter_gather_total_pte_requests,
-+ int_to_fixed(64)));
-+ results->total_display_reads_required_dram_access_data = add(
-+ add(results->total_display_reads_required_dram_access_data,
-+ results->cursor_total_data),
-+ mul(results->scatter_gather_total_pte_requests,
-+ int_to_fixed(64)));
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (gtn(results->v_filter_init[i], int_to_fixed(4))) {
-+ results->src_pixels_for_first_output_pixel[i] =
-+ mul(
-+ results->source_width_rounded_up_to_chunks[i],
-+ int_to_fixed(4));
-+ } else {
-+ if (gtn(results->v_filter_init[i],
-+ int_to_fixed(2))) {
-+ results->src_pixels_for_first_output_pixel[i] =
-+ int_to_fixed(512);
-+ } else {
-+ results->src_pixels_for_first_output_pixel[i] =
-+ int_to_fixed(0);
-+ }
-+ }
-+ results->src_data_for_first_output_pixel[i] =
-+ bw_div(
-+ mul(
-+ mul(
-+ results->src_pixels_for_first_output_pixel[i],
-+ results->bytes_per_pixel[i]),
-+ results->bytes_per_request[i]),
-+ results->useful_bytes_per_request[i]);
-+ results->src_pixels_for_last_output_pixel[i] =
-+ mul(
-+ results->source_width_rounded_up_to_chunks[i],
-+ bw_max(
-+ bw_ceil(
-+ results->v_filter_init[i],
-+ dceip->lines_interleaved_into_lb),
-+ mul(
-+ results->horizontal_blank_and_chunk_granularity_factor[i],
-+ bw_ceil(results->vsr[i],
-+ dceip->lines_interleaved_into_lb))));
-+ results->src_data_for_last_output_pixel[i] =
-+ bw_div(
-+ mul(
-+ mul(
-+ mul(
-+ results->source_width_rounded_up_to_chunks[i],
-+ bw_max(
-+ bw_ceil(
-+ results->v_filter_init[i],
-+ dceip->lines_interleaved_into_lb),
-+ results->lines_interleaved_in_mem_access[i])),
-+ results->bytes_per_pixel[i]),
-+ results->bytes_per_request[i]),
-+ results->useful_bytes_per_request[i]);
-+ results->active_time[i] =
-+ bw_div(
-+ bw_div(
-+ results->source_width_rounded_up_to_chunks[i],
-+ results->hsr[i]),
-+ results->pixel_rate[i]);
-+ }
-+ }
-+ for (i = 0; i <= 2; i += 1) {
-+ for (j = 0; j <= 2; j += 1) {
-+ results->dmif_burst_time[i][j] =
-+ bw_max3(
-+ results->dmif_total_page_close_open_time,
-+ bw_div(
-+ results->total_display_reads_required_dram_access_data,
-+ (mul(
-+ bw_div(
-+ mul(yclk[i],
-+ vbios->dram_channel_width_in_bits),
-+ int_to_fixed(
-+ 8)),
-+ vbios->number_of_dram_channels))),
-+ bw_div(
-+ results->total_display_reads_required_data,
-+ (mul(sclk[j],
-+ vbios->data_return_bus_width))));
-+ if (mode_data->d1_display_write_back_dwb_enable
-+ == true) {
-+ results->mcifwr_burst_time[i][j] =
-+ bw_max3(
-+ results->mcifwr_total_page_close_open_time,
-+ bw_div(
-+ results->total_display_writes_required_dram_access_data,
-+ (mul(
-+ bw_div(
-+ mul(
-+ yclk[i],
-+ vbios->dram_channel_width_in_bits),
-+ int_to_fixed(
-+ 8)),
-+ vbios->number_of_dram_channels))),
-+ bw_div(
-+ results->total_display_writes_required_data,
-+ (mul(sclk[j],
-+ vbios->data_return_bus_width))));
-+ }
-+ }
-+ }
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ for (j = 0; j <= 2; j += 1) {
-+ for (k = 0; k <= 2; k += 1) {
-+ if (results->enable[i]) {
-+ if (surface_type[i]
-+ != def_display_write_back420_luma
-+ && surface_type[i]
-+ != def_display_write_back420_chroma) {
-+ results->line_source_transfer_time[i][j][k] =
-+ bw_max(
-+ mul(
-+ (add(
-+ results->total_dmifmc_urgent_latency,
-+ results->dmif_burst_time[j][k])),
-+ bw_floor(
-+ bw_div(
-+ results->src_data_for_first_output_pixel[i],
-+ results->adjusted_data_buffer_size_in_memory[i]),
-+ int_to_fixed(
-+ 1))),
-+ sub(
-+ mul(
-+ (add(
-+ results->total_dmifmc_urgent_latency,
-+ results->dmif_burst_time[j][k])),
-+ bw_floor(
-+ bw_div(
-+ results->src_data_for_last_output_pixel[i],
-+ results->adjusted_data_buffer_size_in_memory[i]),
-+ int_to_fixed(
-+ 1))),
-+ results->active_time[i]));
-+ } else {
-+ results->line_source_transfer_time[i][j][k] =
-+ bw_max(
-+ mul(
-+ (add(
-+ vbios->mcifwrmc_urgent_latency,
-+ results->mcifwr_burst_time[j][k])),
-+ bw_floor(
-+ bw_div(
-+ results->src_data_for_first_output_pixel[i],
-+ results->adjusted_data_buffer_size_in_memory[i]),
-+ int_to_fixed(
-+ 1))),
-+ sub(
-+ mul(
-+ (add(
-+ vbios->mcifwrmc_urgent_latency,
-+ results->mcifwr_burst_time[j][k])),
-+ bw_floor(
-+ bw_div(
-+ results->src_data_for_last_output_pixel[i],
-+ results->adjusted_data_buffer_size_in_memory[i]),
-+ int_to_fixed(
-+ 1))),
-+ results->active_time[i]));
-+ }
-+ }
-+ }
-+ }
-+ }
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (equ(
-+ dceip->stutter_and_dram_clock_state_change_gated_before_cursor,
-+ int_to_fixed(0))
-+ && gtn(results->cursor_width_pixels[i],
-+ int_to_fixed(0))) {
-+ if (ltn(results->vsr[i], int_to_fixed(2))) {
-+ results->cursor_latency_hiding[i] =
-+ bw_div(
-+ bw_div(
-+ mul(
-+ (sub(
-+ dceip->cursor_dcp_buffer_lines,
-+ int_to_fixed(
-+ 1))),
-+ results->h_total[i]),
-+ results->vsr[i]),
-+ results->pixel_rate[i]);
-+ } else {
-+ results->cursor_latency_hiding[i] =
-+ bw_div(
-+ bw_div(
-+ mul(
-+ (sub(
-+ dceip->cursor_dcp_buffer_lines,
-+ int_to_fixed(
-+ 3))),
-+ results->h_total[i]),
-+ results->vsr[i]),
-+ results->pixel_rate[i]);
-+ }
-+ } else {
-+ results->cursor_latency_hiding[i] =
-+ int_to_fixed(9999);
-+ }
-+ }
-+ }
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (dceip->graphics_lb_nodownscaling_multi_line_prefetching
-+ == true
-+ && (equ(results->vsr[i], int_to_fixed(1))
-+ || (leq(results->vsr[i],
-+ frc_to_fixed(8, 10))
-+ && leq(results->v_taps[i],
-+ int_to_fixed(2))
-+ && equ(results->lb_bpc[i],
-+ int_to_fixed(8))))
-+ && surface_type[i] == def_graphics) {
-+ results->minimum_latency_hiding[i] =
-+ sub(
-+ sub(
-+ add(
-+ bw_div(
-+ mul(
-+ bw_div(
-+ (bw_div(
-+ bw_div(
-+ results->data_buffer_size[i],
-+ results->bytes_per_pixel[i]),
-+ results->source_width_pixels[i])),
-+ results->vsr[i]),
-+ results->h_total[i]),
-+ results->pixel_rate[i]),
-+ results->lb_partitions[i]),
-+ int_to_fixed(1)),
-+ results->total_dmifmc_urgent_latency);
-+ } else {
-+ results->minimum_latency_hiding[i] =
-+ sub(
-+ bw_div(
-+ mul(
-+ (add(
-+ add(
-+ results->line_buffer_prefetch[i],
-+ int_to_fixed(
-+ 1)),
-+ bw_div(
-+ bw_div(
-+ bw_div(
-+ results->data_buffer_size[i],
-+ results->bytes_per_pixel[i]),
-+ results->source_width_pixels[i]),
-+ results->vsr[i]))),
-+ results->h_total[i]),
-+ results->pixel_rate[i]),
-+ results->total_dmifmc_urgent_latency);
-+ }
-+ results->minimum_latency_hiding_with_cursor[i] = bw_min(
-+ results->minimum_latency_hiding[i],
-+ results->cursor_latency_hiding[i]);
-+ }
-+ }
-+ for (i = 0; i <= 2; i += 1) {
-+ for (j = 0; j <= 2; j += 1) {
-+ results->blackout_duration_margin[i][j] = int_to_fixed(
-+ 9999);
-+ results->dispclk_required_for_blackout_duration[i][j] =
-+ int_to_fixed(0);
-+ results->dispclk_required_for_blackout_recovery[i][j] =
-+ int_to_fixed(0);
-+ for (k = 0; k <= maximum_number_of_surfaces - 1; k +=
-+ 1) {
-+ if (results->enable[k]
-+ && gtn(vbios->blackout_duration,
-+ int_to_fixed(0))) {
-+ if (surface_type[k]
-+ != def_display_write_back420_luma
-+ && surface_type[k]
-+ != def_display_write_back420_chroma) {
-+ results->blackout_duration_margin[i][j] =
-+ bw_min(
-+ results->blackout_duration_margin[i][j],
-+ sub(
-+ sub(
-+ sub(
-+ results->minimum_latency_hiding_with_cursor[k],
-+ vbios->blackout_duration),
-+ results->dmif_burst_time[i][j]),
-+ results->line_source_transfer_time[k][i][j]));
-+ results->dispclk_required_for_blackout_duration[i][j] =
-+ bw_max3(
-+ results->dispclk_required_for_blackout_duration[i][j],
-+ bw_div(
-+ bw_div(
-+ mul(
-+ results->src_pixels_for_first_output_pixel[k],
-+ dceip->display_pipe_throughput_factor),
-+ dceip->lb_write_pixels_per_dispclk),
-+ (sub(
-+ sub(
-+ results->minimum_latency_hiding_with_cursor[k],
-+ vbios->blackout_duration),
-+ results->dmif_burst_time[i][j]))),
-+ bw_div(
-+ bw_div(
-+ mul(
-+ results->src_pixels_for_last_output_pixel[k],
-+ dceip->display_pipe_throughput_factor),
-+ dceip->lb_write_pixels_per_dispclk),
-+ (add(
-+ sub(
-+ sub(
-+ results->minimum_latency_hiding_with_cursor[k],
-+ vbios->blackout_duration),
-+ results->dmif_burst_time[i][j]),
-+ results->active_time[k]))));
-+ if (leq(
-+ vbios->maximum_blackout_recovery_time,
-+ add(
-+ mul(
-+ results->total_dmifmc_urgent_latency,
-+ int_to_fixed(
-+ 2)),
-+ results->dmif_burst_time[i][j]))) {
-+ results->dispclk_required_for_blackout_recovery[i][j] =
-+ int_to_fixed(
-+ 9999);
-+ } else if (ltn(
-+ results->adjusted_data_buffer_size[k],
-+ mul(
-+ bw_div(
-+ mul(
-+ results->display_bandwidth[k],
-+ results->useful_bytes_per_request[k]),
-+ results->bytes_per_request[k]),
-+ (add(
-+ add(
-+ vbios->blackout_duration,
-+ mul(
-+ results->total_dmifmc_urgent_latency,
-+ int_to_fixed(
-+ 2))),
-+ results->dmif_burst_time[i][j]))))) {
-+ results->dispclk_required_for_blackout_recovery[i][j] =
-+ bw_max(
-+ results->dispclk_required_for_blackout_recovery[i][j],
-+ bw_div(
-+ mul(
-+ bw_div(
-+ bw_div(
-+ (sub(
-+ mul(
-+ bw_div(
-+ mul(
-+ results->display_bandwidth[k],
-+ results->useful_bytes_per_request[k]),
-+ results->bytes_per_request[k]),
-+ (add(
-+ vbios->blackout_duration,
-+ vbios->maximum_blackout_recovery_time))),
-+ results->adjusted_data_buffer_size[k])),
-+ results->bytes_per_pixel[k]),
-+ (sub(
-+ sub(
-+ vbios->maximum_blackout_recovery_time,
-+ mul(
-+ results->total_dmifmc_urgent_latency,
-+ int_to_fixed(
-+ 2))),
-+ results->dmif_burst_time[i][j]))),
-+ results->latency_hiding_lines[k]),
-+ results->lines_interleaved_in_mem_access[k]));
-+ }
-+ } else {
-+ results->blackout_duration_margin[i][j] =
-+ bw_min(
-+ results->blackout_duration_margin[i][j],
-+ sub(
-+ sub(
-+ sub(
-+ sub(
-+ results->minimum_latency_hiding_with_cursor[k],
-+ vbios->blackout_duration),
-+ results->dmif_burst_time[i][j]),
-+ results->mcifwr_burst_time[i][j]),
-+ results->line_source_transfer_time[k][i][j]));
-+ results->dispclk_required_for_blackout_duration[i][j] =
-+ bw_max3(
-+ results->dispclk_required_for_blackout_duration[i][j],
-+ bw_div(
-+ bw_div(
-+ mul(
-+ results->src_pixels_for_first_output_pixel[k],
-+ dceip->display_pipe_throughput_factor),
-+ dceip->lb_write_pixels_per_dispclk),
-+ (sub(
-+ sub(
-+ sub(
-+ results->minimum_latency_hiding_with_cursor[k],
-+ vbios->blackout_duration),
-+ results->dmif_burst_time[i][j]),
-+ results->mcifwr_burst_time[i][j]))),
-+ bw_div(
-+ bw_div(
-+ mul(
-+ results->src_pixels_for_last_output_pixel[k],
-+ dceip->display_pipe_throughput_factor),
-+ dceip->lb_write_pixels_per_dispclk),
-+ (add(
-+ sub(
-+ sub(
-+ sub(
-+ results->minimum_latency_hiding_with_cursor[k],
-+ vbios->blackout_duration),
-+ results->dmif_burst_time[i][j]),
-+ results->mcifwr_burst_time[i][j]),
-+ results->active_time[k]))));
-+ if (ltn(
-+ vbios->maximum_blackout_recovery_time,
-+ add(
-+ add(
-+ mul(
-+ vbios->mcifwrmc_urgent_latency,
-+ int_to_fixed(
-+ 2)),
-+ results->dmif_burst_time[i][j]),
-+ results->mcifwr_burst_time[i][j]))) {
-+ results->dispclk_required_for_blackout_recovery[i][j] =
-+ int_to_fixed(
-+ 9999);
-+ } else if (ltn(
-+ results->adjusted_data_buffer_size[k],
-+ mul(
-+ bw_div(
-+ mul(
-+ results->display_bandwidth[k],
-+ results->useful_bytes_per_request[k]),
-+ results->bytes_per_request[k]),
-+ (add(
-+ add(
-+ vbios->blackout_duration,
-+ mul(
-+ results->total_dmifmc_urgent_latency,
-+ int_to_fixed(
-+ 2))),
-+ results->dmif_burst_time[i][j]))))) {
-+ results->dispclk_required_for_blackout_recovery[i][j] =
-+ bw_max(
-+ results->dispclk_required_for_blackout_recovery[i][j],
-+ bw_div(
-+ mul(
-+ bw_div(
-+ bw_div(
-+ (sub(
-+ mul(
-+ bw_div(
-+ mul(
-+ results->display_bandwidth[k],
-+ results->useful_bytes_per_request[k]),
-+ results->bytes_per_request[k]),
-+ (add(
-+ vbios->blackout_duration,
-+ vbios->maximum_blackout_recovery_time))),
-+ results->adjusted_data_buffer_size[k])),
-+ results->bytes_per_pixel[k]),
-+ (sub(
-+ vbios->maximum_blackout_recovery_time,
-+ (add(
-+ mul(
-+ results->total_dmifmc_urgent_latency,
-+ int_to_fixed(
-+ 2)),
-+ results->dmif_burst_time[i][j]))))),
-+ results->latency_hiding_lines[k]),
-+ results->lines_interleaved_in_mem_access[k]));
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+ if (gtn(results->blackout_duration_margin[high][high], int_to_fixed(0))
-+ && ltn(
-+ results->dispclk_required_for_blackout_duration[high][high],
-+ vbios->high_voltage_max_dispclk)) {
-+ results->cpup_state_change_enable = true;
-+ if (ltn(
-+ results->dispclk_required_for_blackout_recovery[high][high],
-+ vbios->high_voltage_max_dispclk)) {
-+ results->cpuc_state_change_enable = true;
-+ } else {
-+ results->cpuc_state_change_enable = false;
-+ }
-+ } else {
-+ results->cpup_state_change_enable = false;
-+ results->cpuc_state_change_enable = false;
-+ }
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (mode_data->number_of_displays <= 1
-+ || mode_data->display_synchronization_enabled
-+ == true) {
-+ results->maximum_latency_hiding[i] =
-+ int_to_fixed(450);
-+ } else {
-+ results->maximum_latency_hiding[i] =
-+ add(
-+ add(
-+ results->minimum_latency_hiding[i],
-+ bw_div(
-+ mul(
-+ bw_div(
-+ int_to_fixed(
-+ 1),
-+ results->vsr[i]),
-+ results->h_total[i]),
-+ results->pixel_rate[i])),
-+ mul(frc_to_fixed(1, 2),
-+ results->total_dmifmc_urgent_latency));
-+ }
-+ results->maximum_latency_hiding_with_cursor[i] = bw_min(
-+ results->maximum_latency_hiding[i],
-+ results->cursor_latency_hiding[i]);
-+ }
-+ }
-+ for (i = 0; i <= 2; i += 1) {
-+ for (j = 0; j <= 2; j += 1) {
-+ results->dram_speed_change_margin[i][j] = int_to_fixed(
-+ 9999);
-+ results->dispclk_required_for_dram_speed_change[i][j] =
-+ int_to_fixed(0);
-+ for (k = 0; k <= maximum_number_of_surfaces - 1; k +=
-+ 1) {
-+ if (results->enable[k]) {
-+ if (surface_type[k]
-+ != def_display_write_back420_luma
-+ && surface_type[k]
-+ != def_display_write_back420_chroma) {
-+ results->dram_speed_change_margin[i][j] =
-+ bw_min(
-+ results->dram_speed_change_margin[i][j],
-+ sub(
-+ sub(
-+ sub(
-+ results->maximum_latency_hiding_with_cursor[k],
-+ vbios->nbp_state_change_latency),
-+ results->dmif_burst_time[i][j]),
-+ results->line_source_transfer_time[k][i][j]));
-+ results->dispclk_required_for_dram_speed_change[i][j] =
-+ bw_max3(
-+ results->dispclk_required_for_dram_speed_change[i][j],
-+ bw_div(
-+ bw_div(
-+ mul(
-+ results->src_pixels_for_first_output_pixel[k],
-+ dceip->display_pipe_throughput_factor),
-+ dceip->lb_write_pixels_per_dispclk),
-+ (sub(
-+ sub(
-+ results->maximum_latency_hiding_with_cursor[k],
-+ vbios->nbp_state_change_latency),
-+ results->dmif_burst_time[i][j]))),
-+ bw_div(
-+ bw_div(
-+ mul(
-+ results->src_pixels_for_last_output_pixel[k],
-+ dceip->display_pipe_throughput_factor),
-+ dceip->lb_write_pixels_per_dispclk),
-+ (add(
-+ sub(
-+ sub(
-+ results->maximum_latency_hiding_with_cursor[k],
-+ vbios->nbp_state_change_latency),
-+ results->dmif_burst_time[i][j]),
-+ results->active_time[k]))));
-+ } else {
-+ results->dram_speed_change_margin[i][j] =
-+ bw_min(
-+ results->dram_speed_change_margin[i][j],
-+ sub(
-+ sub(
-+ sub(
-+ sub(
-+ results->maximum_latency_hiding_with_cursor[k],
-+ vbios->nbp_state_change_latency),
-+ results->dmif_burst_time[i][j]),
-+ results->mcifwr_burst_time[i][j]),
-+ results->line_source_transfer_time[k][i][j]));
-+ results->dispclk_required_for_dram_speed_change[i][j] =
-+ bw_max3(
-+ results->dispclk_required_for_dram_speed_change[i][j],
-+ bw_div(
-+ bw_div(
-+ mul(
-+ results->src_pixels_for_first_output_pixel[k],
-+ dceip->display_pipe_throughput_factor),
-+ dceip->lb_write_pixels_per_dispclk),
-+ (sub(
-+ sub(
-+ sub(
-+ results->maximum_latency_hiding_with_cursor[k],
-+ vbios->nbp_state_change_latency),
-+ results->dmif_burst_time[i][j]),
-+ results->mcifwr_burst_time[i][j]))),
-+ bw_div(
-+ bw_div(
-+ mul(
-+ results->src_pixels_for_last_output_pixel[k],
-+ dceip->display_pipe_throughput_factor),
-+ dceip->lb_write_pixels_per_dispclk),
-+ (add(
-+ sub(
-+ sub(
-+ sub(
-+ results->maximum_latency_hiding_with_cursor[k],
-+ vbios->nbp_state_change_latency),
-+ results->dmif_burst_time[i][j]),
-+ results->mcifwr_burst_time[i][j]),
-+ results->active_time[k]))));
-+ }
-+ }
-+ }
-+ }
-+ }
-+ if (gtn(results->dram_speed_change_margin[high][high], int_to_fixed(0))
-+ && ltn(
-+ results->dispclk_required_for_dram_speed_change[high][high],
-+ vbios->high_voltage_max_dispclk)) {
-+ results->nbp_state_change_enable = true;
-+ } else {
-+ results->nbp_state_change_enable = false;
-+ }
-+ results->min_cursor_memory_interface_buffer_size_in_time = int_to_fixed(
-+ 9999);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (gtn(results->cursor_width_pixels[i],
-+ int_to_fixed(0))) {
-+ results->min_cursor_memory_interface_buffer_size_in_time =
-+ bw_min(
-+ results->min_cursor_memory_interface_buffer_size_in_time,
-+ bw_div(
-+ mul(
-+ bw_div(
-+ bw_div(
-+ dceip->cursor_memory_interface_buffer_pixels,
-+ results->cursor_width_pixels[i]),
-+ results->vsr[i]),
-+ results->h_total[i]),
-+ results->pixel_rate[i]));
-+ }
-+ }
-+ }
-+ results->min_read_buffer_size_in_time = bw_min(
-+ results->min_cursor_memory_interface_buffer_size_in_time,
-+ results->min_dmif_size_in_time);
-+ results->display_reads_time_for_data_transfer = sub(
-+ results->min_read_buffer_size_in_time,
-+ results->total_dmifmc_urgent_latency);
-+ results->display_writes_time_for_data_transfer = sub(
-+ results->min_mcifwr_size_in_time,
-+ vbios->mcifwrmc_urgent_latency);
-+ results->dmif_required_dram_bandwidth = bw_div(
-+ results->total_display_reads_required_dram_access_data,
-+ results->display_reads_time_for_data_transfer);
-+ results->mcifwr_required_dram_bandwidth = bw_div(
-+ results->total_display_writes_required_dram_access_data,
-+ results->display_writes_time_for_data_transfer);
-+ results->required_dmifmc_urgent_latency_for_page_close_open = bw_div(
-+ (sub(results->min_read_buffer_size_in_time,
-+ results->dmif_total_page_close_open_time)),
-+ results->total_dmifmc_urgent_trips);
-+ results->required_mcifmcwr_urgent_latency = sub(
-+ results->min_mcifwr_size_in_time,
-+ results->mcifwr_total_page_close_open_time);
-+ if (gtn(results->scatter_gather_total_pte_requests,
-+ dceip->maximum_total_outstanding_pte_requests_allowed_by_saw)) {
-+ results->required_dram_bandwidth_gbyte_per_second =
-+ int_to_fixed(9999);
-+ yclk_message =
-+ def_exceeded_allowed_outstanding_pte_req_queue_size;
-+ y_clk_level = high;
-+ results->dram_bandwidth = mul(
-+ bw_div(
-+ mul(vbios->high_yclk,
-+ vbios->dram_channel_width_in_bits),
-+ int_to_fixed(8)),
-+ vbios->number_of_dram_channels);
-+ } else if (gtn(vbios->dmifmc_urgent_latency,
-+ results->required_dmifmc_urgent_latency_for_page_close_open)
-+ || gtn(vbios->mcifwrmc_urgent_latency,
-+ results->required_mcifmcwr_urgent_latency)) {
-+ results->required_dram_bandwidth_gbyte_per_second =
-+ int_to_fixed(9999);
-+ yclk_message = def_exceeded_allowed_page_close_open;
-+ y_clk_level = high;
-+ results->dram_bandwidth = mul(
-+ bw_div(
-+ mul(vbios->high_yclk,
-+ vbios->dram_channel_width_in_bits),
-+ int_to_fixed(8)),
-+ vbios->number_of_dram_channels);
-+ } else {
-+ results->required_dram_bandwidth_gbyte_per_second = bw_div(
-+ bw_max(results->dmif_required_dram_bandwidth,
-+ results->mcifwr_required_dram_bandwidth),
-+ int_to_fixed(1000));
-+ if (ltn(
-+ mul(results->required_dram_bandwidth_gbyte_per_second,
-+ int_to_fixed(1000)),
-+ mul(
-+ bw_div(
-+ mul(vbios->low_yclk,
-+ vbios->dram_channel_width_in_bits),
-+ int_to_fixed(8)),
-+ vbios->number_of_dram_channels))
-+ && (results->cpup_state_change_enable == false
-+ || (gtn(
-+ results->blackout_duration_margin[low][high],
-+ int_to_fixed(0))
-+ && ltn(
-+ results->dispclk_required_for_blackout_duration[low][high],
-+ vbios->high_voltage_max_dispclk)))
-+ && (results->cpuc_state_change_enable == false
-+ || (gtn(
-+ results->blackout_duration_margin[low][high],
-+ int_to_fixed(0))
-+ && ltn(
-+ results->dispclk_required_for_blackout_duration[low][high],
-+ vbios->high_voltage_max_dispclk)
-+ && ltn(
-+ results->dispclk_required_for_blackout_recovery[low][high],
-+ vbios->high_voltage_max_dispclk)))
-+ && gtn(results->dram_speed_change_margin[low][high],
-+ int_to_fixed(0))
-+ && ltn(
-+ results->dispclk_required_for_dram_speed_change[low][high],
-+ vbios->high_voltage_max_dispclk)) {
-+ yclk_message = def_low;
-+ y_clk_level = low;
-+ results->dram_bandwidth =
-+ mul(
-+ bw_div(
-+ mul(vbios->low_yclk,
-+ vbios->dram_channel_width_in_bits),
-+ int_to_fixed(8)),
-+ vbios->number_of_dram_channels);
-+ } else if (ltn(
-+ mul(results->required_dram_bandwidth_gbyte_per_second,
-+ int_to_fixed(1000)),
-+ mul(
-+ bw_div(
-+ mul(vbios->high_yclk,
-+ vbios->dram_channel_width_in_bits),
-+ int_to_fixed(8)),
-+ vbios->number_of_dram_channels))) {
-+ yclk_message = def_high;
-+ y_clk_level = high;
-+ results->dram_bandwidth =
-+ mul(
-+ bw_div(
-+ mul(vbios->high_yclk,
-+ vbios->dram_channel_width_in_bits),
-+ int_to_fixed(8)),
-+ vbios->number_of_dram_channels);
-+ } else {
-+ yclk_message = def_exceeded_allowed_maximum_bw;
-+ y_clk_level = high;
-+ results->dram_bandwidth =
-+ mul(
-+ bw_div(
-+ mul(vbios->high_yclk,
-+ vbios->dram_channel_width_in_bits),
-+ int_to_fixed(8)),
-+ vbios->number_of_dram_channels);
-+ }
-+ }
-+ results->dmif_required_sclk = bw_div(
-+ bw_div(results->total_display_reads_required_data,
-+ results->display_reads_time_for_data_transfer),
-+ vbios->data_return_bus_width);
-+ results->mcifwr_required_sclk = bw_div(
-+ bw_div(results->total_display_writes_required_data,
-+ results->display_writes_time_for_data_transfer),
-+ vbios->data_return_bus_width);
-+ if (gtn(results->scatter_gather_total_pte_requests,
-+ dceip->maximum_total_outstanding_pte_requests_allowed_by_saw)) {
-+ results->required_sclk = int_to_fixed(9999);
-+ sclk_message =
-+ def_exceeded_allowed_outstanding_pte_req_queue_size;
-+ sclk_level = high;
-+ } else if (gtn(vbios->dmifmc_urgent_latency,
-+ results->required_dmifmc_urgent_latency_for_page_close_open)
-+ || gtn(vbios->mcifwrmc_urgent_latency,
-+ results->required_mcifmcwr_urgent_latency)) {
-+ results->required_sclk = int_to_fixed(9999);
-+ sclk_message = def_exceeded_allowed_page_close_open;
-+ sclk_level = high;
-+ } else {
-+ results->required_sclk = bw_max(results->dmif_required_sclk,
-+ results->mcifwr_required_sclk);
-+ if (ltn(results->required_sclk, vbios->low_sclk)
-+ && (results->cpup_state_change_enable == false
-+ || (gtn(
-+ results->blackout_duration_margin[y_clk_level][low],
-+ int_to_fixed(0))
-+ && ltn(
-+ results->dispclk_required_for_blackout_duration[y_clk_level][low],
-+ vbios->high_voltage_max_dispclk)))
-+ && (results->cpuc_state_change_enable == false
-+ || (gtn(
-+ results->blackout_duration_margin[y_clk_level][low],
-+ int_to_fixed(0))
-+ && ltn(
-+ results->dispclk_required_for_blackout_duration[y_clk_level][low],
-+ vbios->high_voltage_max_dispclk)
-+ && ltn(
-+ results->dispclk_required_for_blackout_recovery[y_clk_level][low],
-+ vbios->high_voltage_max_dispclk)))
-+ && (results->nbp_state_change_enable == false
-+ || (gtn(
-+ results->dram_speed_change_margin[y_clk_level][low],
-+ int_to_fixed(0))
-+ && leq(
-+ results->dispclk_required_for_dram_speed_change[y_clk_level][low],
-+ vbios->high_voltage_max_dispclk)))) {
-+ sclk_message = def_low;
-+ sclk_level = low;
-+ } else if (ltn(results->required_sclk, vbios->mid_sclk)
-+ && (results->cpup_state_change_enable == false
-+ || (gtn(
-+ results->blackout_duration_margin[y_clk_level][mid],
-+ int_to_fixed(0))
-+ && ltn(
-+ results->dispclk_required_for_blackout_duration[y_clk_level][mid],
-+ vbios->high_voltage_max_dispclk)))
-+ && (results->cpuc_state_change_enable == false
-+ || (gtn(
-+ results->blackout_duration_margin[y_clk_level][mid],
-+ int_to_fixed(0))
-+ && ltn(
-+ results->dispclk_required_for_blackout_duration[y_clk_level][mid],
-+ vbios->high_voltage_max_dispclk)
-+ && ltn(
-+ results->dispclk_required_for_blackout_recovery[y_clk_level][mid],
-+ vbios->high_voltage_max_dispclk)))
-+ && (results->nbp_state_change_enable == false
-+ || (gtn(
-+ results->dram_speed_change_margin[y_clk_level][mid],
-+ int_to_fixed(0))
-+ && leq(
-+ results->dispclk_required_for_dram_speed_change[y_clk_level][mid],
-+ vbios->high_voltage_max_dispclk)))) {
-+ sclk_message = def_mid;
-+ sclk_level = mid;
-+ } else if (ltn(results->required_sclk, vbios->high_sclk)) {
-+ sclk_message = def_high;
-+ sclk_level = high;
-+ } else {
-+ sclk_message = def_exceeded_allowed_maximum_sclk;
-+ sclk_level = high;
-+ }
-+ }
-+ results->downspread_factor = add(
-+ bw_div(vbios->down_spread_percentage, int_to_fixed(100)),
-+ int_to_fixed(1));
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (surface_type[i] == def_graphics) {
-+ if (equ(results->lb_bpc[i], int_to_fixed(6))) {
-+ results->v_scaler_efficiency =
-+ dceip->graphics_vscaler_efficiency6_bit_per_component;
-+ } else if (equ(results->lb_bpc[i],
-+ int_to_fixed(8))) {
-+ results->v_scaler_efficiency =
-+ dceip->graphics_vscaler_efficiency8_bit_per_component;
-+ } else if (equ(results->lb_bpc[i],
-+ int_to_fixed(10))) {
-+ results->v_scaler_efficiency =
-+ dceip->graphics_vscaler_efficiency10_bit_per_component;
-+ } else {
-+ results->v_scaler_efficiency =
-+ dceip->graphics_vscaler_efficiency12_bit_per_component;
-+ }
-+ if (results->use_alpha[i] == true) {
-+ results->v_scaler_efficiency =
-+ bw_min(
-+ results->v_scaler_efficiency,
-+ dceip->alpha_vscaler_efficiency);
-+ }
-+ } else {
-+ if (equ(results->lb_bpc[i], int_to_fixed(6))) {
-+ results->v_scaler_efficiency =
-+ dceip->underlay_vscaler_efficiency6_bit_per_component;
-+ } else if (equ(results->lb_bpc[i],
-+ int_to_fixed(8))) {
-+ results->v_scaler_efficiency =
-+ dceip->underlay_vscaler_efficiency8_bit_per_component;
-+ } else if (equ(results->lb_bpc[i],
-+ int_to_fixed(10))) {
-+ results->v_scaler_efficiency =
-+ dceip->underlay_vscaler_efficiency10_bit_per_component;
-+ } else {
-+ results->v_scaler_efficiency =
-+ dceip->underlay_vscaler_efficiency12_bit_per_component;
-+ }
-+ }
-+ if (dceip->pre_downscaler_enabled
-+ && gtn(results->hsr[i], int_to_fixed(1))) {
-+ results->scaler_limits_factor =
-+ bw_max(
-+ bw_div(results->v_taps[i],
-+ results->v_scaler_efficiency),
-+ bw_div(
-+ results->source_width_rounded_up_to_chunks[i],
-+ results->h_total[i]));
-+ } else {
-+ results->scaler_limits_factor =
-+ bw_max3(int_to_fixed(1),
-+ bw_ceil(
-+ bw_div(results->h_taps[i],
-+ int_to_fixed(
-+ 4)),
-+ int_to_fixed(1)),
-+ mul(results->hsr[i],
-+ bw_max(
-+ bw_div(
-+ results->v_taps[i],
-+ results->v_scaler_efficiency),
-+ int_to_fixed(
-+ 1))));
-+ }
-+ results->display_pipe_pixel_throughput =
-+ bw_div(
-+ bw_div(
-+ mul(
-+ bw_max(
-+ results->lb_lines_in_per_line_out_in_beginning_of_frame[i],
-+ mul(
-+ results->lb_lines_in_per_line_out_in_middle_of_frame[i],
-+ results->horizontal_blank_and_chunk_granularity_factor[i])),
-+ results->source_width_rounded_up_to_chunks[i]),
-+ (bw_div(results->h_total[i],
-+ results->pixel_rate[i]))),
-+ dceip->lb_write_pixels_per_dispclk);
-+ results->dispclk_required_without_ramping[i] =
-+ mul(results->downspread_factor,
-+ bw_max(
-+ mul(results->pixel_rate[i],
-+ results->scaler_limits_factor),
-+ mul(
-+ dceip->display_pipe_throughput_factor,
-+ results->display_pipe_pixel_throughput)));
-+ results->dispclk_required_with_ramping[i] =
-+ mul(dceip->dispclk_ramping_factor,
-+ bw_max(
-+ mul(results->pixel_rate[i],
-+ results->scaler_limits_factor),
-+ results->display_pipe_pixel_throughput));
-+ }
-+ }
-+ results->total_dispclk_required_with_ramping = int_to_fixed(0);
-+ results->total_dispclk_required_without_ramping = int_to_fixed(0);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (ltn(results->total_dispclk_required_with_ramping,
-+ results->dispclk_required_with_ramping[i])) {
-+ results->total_dispclk_required_with_ramping =
-+ results->dispclk_required_with_ramping[i];
-+ }
-+ if (ltn(results->total_dispclk_required_without_ramping,
-+ results->dispclk_required_without_ramping[i])) {
-+ results->total_dispclk_required_without_ramping =
-+ results->dispclk_required_without_ramping[i];
-+ }
-+ }
-+ }
-+ results->total_read_request_bandwidth = int_to_fixed(0);
-+ results->total_write_request_bandwidth = int_to_fixed(0);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (surface_type[i] != def_display_write_back420_luma
-+ && surface_type[i]
-+ != def_display_write_back420_chroma) {
-+ results->total_read_request_bandwidth = add(
-+ results->total_read_request_bandwidth,
-+ results->request_bandwidth[i]);
-+ } else {
-+ results->total_write_request_bandwidth = add(
-+ results->total_write_request_bandwidth,
-+ results->request_bandwidth[i]);
-+ }
-+ }
-+ }
-+ results->dispclk_required_for_total_read_request_bandwidth = bw_div(
-+ mul(results->total_read_request_bandwidth,
-+ dceip->dispclk_per_request), dceip->request_efficiency);
-+ if (equ(dceip->dcfclk_request_generation, int_to_fixed(0))) {
-+ results->total_dispclk_required_with_ramping_with_request_bandwidth =
-+ bw_max(results->total_dispclk_required_with_ramping,
-+ results->dispclk_required_for_total_read_request_bandwidth);
-+ results->total_dispclk_required_without_ramping_with_request_bandwidth =
-+ bw_max(results->total_dispclk_required_without_ramping,
-+ results->dispclk_required_for_total_read_request_bandwidth);
-+ } else {
-+ results->total_dispclk_required_with_ramping_with_request_bandwidth =
-+ results->total_dispclk_required_with_ramping;
-+ results->total_dispclk_required_without_ramping_with_request_bandwidth =
-+ results->total_dispclk_required_without_ramping;
-+ }
-+ if (results->cpuc_state_change_enable == true) {
-+ results->total_dispclk_required_with_ramping_with_request_bandwidth =
-+ bw_max3(
-+ results->total_dispclk_required_with_ramping_with_request_bandwidth,
-+ results->dispclk_required_for_blackout_duration[y_clk_level][sclk_level],
-+ results->dispclk_required_for_blackout_recovery[y_clk_level][sclk_level]);
-+ results->total_dispclk_required_without_ramping_with_request_bandwidth =
-+ bw_max3(
-+ results->total_dispclk_required_without_ramping_with_request_bandwidth,
-+ results->dispclk_required_for_blackout_duration[y_clk_level][sclk_level],
-+ results->dispclk_required_for_blackout_recovery[y_clk_level][sclk_level]);
-+ }
-+ if (results->cpup_state_change_enable == true) {
-+ results->total_dispclk_required_with_ramping_with_request_bandwidth =
-+ bw_max(
-+ results->total_dispclk_required_with_ramping_with_request_bandwidth,
-+ results->dispclk_required_for_blackout_duration[y_clk_level][sclk_level]);
-+ results->total_dispclk_required_without_ramping_with_request_bandwidth =
-+ bw_max(
-+ results->total_dispclk_required_without_ramping_with_request_bandwidth,
-+ results->dispclk_required_for_blackout_duration[y_clk_level][sclk_level]);
-+ }
-+ if (results->nbp_state_change_enable == true) {
-+ results->total_dispclk_required_with_ramping_with_request_bandwidth =
-+ bw_max(
-+ results->total_dispclk_required_with_ramping_with_request_bandwidth,
-+ results->dispclk_required_for_dram_speed_change[y_clk_level][sclk_level]);
-+ results->total_dispclk_required_without_ramping_with_request_bandwidth =
-+ bw_max(
-+ results->total_dispclk_required_without_ramping_with_request_bandwidth,
-+ results->dispclk_required_for_dram_speed_change[y_clk_level][sclk_level]);
-+ }
-+ if (ltn(
-+ results->total_dispclk_required_with_ramping_with_request_bandwidth,
-+ vbios->high_voltage_max_dispclk)) {
-+ results->dispclk =
-+ results->total_dispclk_required_with_ramping_with_request_bandwidth;
-+ } else if (ltn(
-+ results->total_dispclk_required_without_ramping_with_request_bandwidth,
-+ vbios->high_voltage_max_dispclk)) {
-+ results->dispclk = vbios->high_voltage_max_dispclk;
-+ } else {
-+ results->dispclk =
-+ results->total_dispclk_required_without_ramping_with_request_bandwidth;
-+ }
-+ if (pipe_check == def_notok) {
-+ voltage = def_na;
-+ mode_background_color = def_na_color;
-+ mode_font_color = def_vb_white;
-+ } else if (mode_check == def_notok) {
-+ voltage = def_notok;
-+ mode_background_color = def_notok_color;
-+ mode_font_color = def_vb_black;
-+ } else if (yclk_message == def_low && sclk_message == def_low
-+ && ltn(results->dispclk, vbios->low_voltage_max_dispclk)) {
-+ voltage = def_low;
-+ mode_background_color = def_low_color;
-+ mode_font_color = def_vb_black;
-+ } else if (yclk_message == def_low
-+ && (sclk_message == def_low || sclk_message == def_mid)
-+ && ltn(results->dispclk, vbios->mid_voltage_max_dispclk)) {
-+ voltage = def_mid;
-+ mode_background_color = def_mid_color;
-+ mode_font_color = def_vb_black;
-+ } else if ((yclk_message == def_low || yclk_message == def_high)
-+ && (sclk_message == def_low || sclk_message == def_mid
-+ || sclk_message == def_high)
-+ && leq(results->dispclk, vbios->high_voltage_max_dispclk)) {
-+ if (results->nbp_state_change_enable == true) {
-+ voltage = def_high;
-+ mode_background_color = def_high_color;
-+ mode_font_color = def_vb_black;
-+ } else {
-+ voltage = def_high_no_nbp_state_change;
-+ mode_background_color =
-+ def_high_no_nbp_state_change_color;
-+ mode_font_color = def_vb_black;
-+ }
-+ } else {
-+ voltage = def_notok;
-+ mode_background_color = def_notok_color;
-+ mode_font_color = def_vb_black;
-+ }
-+ if (mode_background_color == def_na_color
-+ || mode_background_color == def_notok_color) {
-+ mode_pattern = def_xl_pattern_solid;
-+ } else if (results->cpup_state_change_enable == false) {
-+ mode_pattern = def_xl_pattern_checker;
-+ } else if (results->cpuc_state_change_enable == false) {
-+ mode_pattern = def_xl_pattern_light_horizontal;
-+ } else {
-+ mode_pattern = def_xl_pattern_solid;
-+ }
-+ results->blackout_recovery_time = int_to_fixed(0);
-+ for (k = 0; k <= maximum_number_of_surfaces - 1; k += 1) {
-+ if (results->enable[k]
-+ && gtn(vbios->blackout_duration, int_to_fixed(0))
-+ && results->cpup_state_change_enable == true) {
-+ if (surface_type[k] != def_display_write_back420_luma
-+ && surface_type[k]
-+ != def_display_write_back420_chroma) {
-+ results->blackout_recovery_time =
-+ bw_max(results->blackout_recovery_time,
-+ add(
-+ mul(
-+ results->total_dmifmc_urgent_latency,
-+ int_to_fixed(
-+ 2)),
-+ results->dmif_burst_time[y_clk_level][sclk_level]));
-+ if (ltn(results->adjusted_data_buffer_size[k],
-+ mul(
-+ bw_div(
-+ mul(
-+ results->display_bandwidth[k],
-+ results->useful_bytes_per_request[k]),
-+ results->bytes_per_request[k]),
-+ (add(
-+ add(
-+ vbios->blackout_duration,
-+ mul(
-+ results->total_dmifmc_urgent_latency,
-+ int_to_fixed(
-+ 2))),
-+ results->dmif_burst_time[y_clk_level][sclk_level]))))) {
-+ results->blackout_recovery_time =
-+ bw_max(
-+ results->blackout_recovery_time,
-+ bw_div(
-+ (sub(
-+ add(
-+ mul(
-+ bw_div(
-+ mul(
-+ results->display_bandwidth[k],
-+ results->useful_bytes_per_request[k]),
-+ results->bytes_per_request[k]),
-+ vbios->blackout_duration),
-+ bw_div(
-+ mul(
-+ mul(
-+ mul(
-+ (add(
-+ mul(
-+ results->total_dmifmc_urgent_latency,
-+ int_to_fixed(
-+ 2)),
-+ results->dmif_burst_time[y_clk_level][sclk_level])),
-+ results->dispclk),
-+ results->bytes_per_pixel[k]),
-+ results->lines_interleaved_in_mem_access[k]),
-+ results->latency_hiding_lines[k])),
-+ results->adjusted_data_buffer_size[k])),
-+ (sub(
-+ bw_div(
-+ mul(
-+ mul(
-+ results->dispclk,
-+ results->bytes_per_pixel[k]),
-+ results->lines_interleaved_in_mem_access[k]),
-+ results->latency_hiding_lines[k]),
-+ bw_div(
-+ mul(
-+ results->display_bandwidth[k],
-+ results->useful_bytes_per_request[k]),
-+ results->bytes_per_request[k])))));
-+ }
-+ } else {
-+ results->blackout_recovery_time =
-+ bw_max(results->blackout_recovery_time,
-+ add(
-+ mul(
-+ vbios->mcifwrmc_urgent_latency,
-+ int_to_fixed(
-+ 2)),
-+ results->mcifwr_burst_time[y_clk_level][sclk_level]));
-+ if (ltn(results->adjusted_data_buffer_size[k],
-+ mul(
-+ bw_div(
-+ mul(
-+ results->display_bandwidth[k],
-+ results->useful_bytes_per_request[k]),
-+ results->bytes_per_request[k]),
-+ (add(
-+ add(
-+ vbios->blackout_duration,
-+ mul(
-+ vbios->mcifwrmc_urgent_latency,
-+ int_to_fixed(
-+ 2))),
-+ results->mcifwr_burst_time[y_clk_level][sclk_level]))))) {
-+ results->blackout_recovery_time =
-+ bw_max(
-+ results->blackout_recovery_time,
-+ bw_div(
-+ (sub(
-+ add(
-+ mul(
-+ bw_div(
-+ mul(
-+ results->display_bandwidth[k],
-+ results->useful_bytes_per_request[k]),
-+ results->bytes_per_request[k]),
-+ vbios->blackout_duration),
-+ bw_div(
-+ mul(
-+ mul(
-+ mul(
-+ (add(
-+ add(
-+ mul(
-+ vbios->mcifwrmc_urgent_latency,
-+ int_to_fixed(
-+ 2)),
-+ results->dmif_burst_time[i][j]),
-+ results->mcifwr_burst_time[y_clk_level][sclk_level])),
-+ results->dispclk),
-+ results->bytes_per_pixel[k]),
-+ results->lines_interleaved_in_mem_access[k]),
-+ results->latency_hiding_lines[k])),
-+ results->adjusted_data_buffer_size[k])),
-+ (sub(
-+ bw_div(
-+ mul(
-+ mul(
-+ results->dispclk,
-+ results->bytes_per_pixel[k]),
-+ results->lines_interleaved_in_mem_access[k]),
-+ results->latency_hiding_lines[k]),
-+ bw_div(
-+ mul(
-+ results->display_bandwidth[k],
-+ results->useful_bytes_per_request[k]),
-+ results->bytes_per_request[k])))));
-+ }
-+ }
-+ }
-+ }
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (surface_type[i] == def_display_write_back420_luma
-+ || surface_type[i]
-+ == def_display_write_back420_chroma) {
-+ results->pixels_per_data_fifo_entry[i] =
-+ int_to_fixed(16);
-+ } else if (surface_type[i] == def_graphics) {
-+ results->pixels_per_data_fifo_entry[i] = bw_div(
-+ int_to_fixed(64),
-+ results->bytes_per_pixel[i]);
-+ } else if (results->orthogonal_rotation[i] == false) {
-+ results->pixels_per_data_fifo_entry[i] =
-+ int_to_fixed(16);
-+ } else {
-+ results->pixels_per_data_fifo_entry[i] = bw_div(
-+ int_to_fixed(16),
-+ results->bytes_per_pixel[i]);
-+ }
-+ }
-+ }
-+ results->min_pixels_per_data_fifo_entry = int_to_fixed(9999);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (gtn(results->min_pixels_per_data_fifo_entry,
-+ results->pixels_per_data_fifo_entry[i])) {
-+ results->min_pixels_per_data_fifo_entry =
-+ results->pixels_per_data_fifo_entry[i];
-+ }
-+ }
-+ }
-+ results->sclk_deep_sleep = bw_max(
-+ bw_div(mul(results->dispclk, frc_to_fixed(115, 100)),
-+ results->min_pixels_per_data_fifo_entry),
-+ results->total_read_request_bandwidth);
-+ results->chunk_request_time = int_to_fixed(0);
-+ results->cursor_request_time = int_to_fixed(0);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ results->chunk_request_time =
-+ add(results->chunk_request_time,
-+ bw_div(
-+ bw_div(
-+ mul(pixels_per_chunk,
-+ results->bytes_per_pixel[i]),
-+ results->useful_bytes_per_request[i]),
-+ bw_min(sclk[sclk_level],
-+ bw_div(results->dispclk,
-+ int_to_fixed(
-+ 2)))));
-+ }
-+ }
-+ results->cursor_request_time = (bw_div(results->cursor_total_data,
-+ (mul(sclk[sclk_level], int_to_fixed(32)))));
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ results->line_source_pixels_transfer_time =
-+ bw_max(
-+ bw_div(
-+ bw_div(
-+ results->src_pixels_for_first_output_pixel[i],
-+ dceip->lb_write_pixels_per_dispclk),
-+ (bw_div(results->dispclk,
-+ dceip->display_pipe_throughput_factor))),
-+ sub(
-+ bw_div(
-+ bw_div(
-+ results->src_pixels_for_last_output_pixel[i],
-+ dceip->lb_write_pixels_per_dispclk),
-+ (bw_div(results->dispclk,
-+ dceip->display_pipe_throughput_factor))),
-+ results->active_time[i]));
-+ if (surface_type[i] != def_display_write_back420_luma
-+ && surface_type[i]
-+ != def_display_write_back420_chroma) {
-+ results->urgent_watermark[i] =
-+ add(
-+ add(
-+ add(
-+ add(
-+ add(
-+ results->total_dmifmc_urgent_latency,
-+ results->dmif_burst_time[y_clk_level][sclk_level]),
-+ bw_max(
-+ results->line_source_pixels_transfer_time,
-+ results->line_source_transfer_time[i][y_clk_level][sclk_level])),
-+ vbios->blackout_duration),
-+ results->chunk_request_time),
-+ results->cursor_request_time);
-+ results->stutter_exit_watermark[i] =
-+ add(
-+ sub(
-+ vbios->stutter_self_refresh_exit_latency,
-+ results->total_dmifmc_urgent_latency),
-+ results->urgent_watermark[i]);
-+ results->nbp_state_change_watermark[i] =
-+ sub(
-+ add(
-+ sub(
-+ vbios->nbp_state_change_latency,
-+ results->total_dmifmc_urgent_latency),
-+ results->urgent_watermark[i]),
-+ vbios->blackout_duration);
-+ } else {
-+ results->urgent_watermark[i] =
-+ add(
-+ add(
-+ add(
-+ add(
-+ add(
-+ vbios->mcifwrmc_urgent_latency,
-+ results->mcifwr_burst_time[y_clk_level][sclk_level]),
-+ bw_max(
-+ results->line_source_pixels_transfer_time,
-+ results->line_source_transfer_time[i][y_clk_level][sclk_level])),
-+ vbios->blackout_duration),
-+ results->chunk_request_time),
-+ results->cursor_request_time);
-+ results->stutter_exit_watermark[i] =
-+ int_to_fixed(0);
-+ results->nbp_state_change_watermark[i] =
-+ add(
-+ sub(
-+ add(
-+ vbios->nbp_state_change_latency,
-+ results->dmif_burst_time[y_clk_level][sclk_level]),
-+ vbios->mcifwrmc_urgent_latency),
-+ results->urgent_watermark[i]);
-+ }
-+ }
-+ }
-+ results->stutter_mode_enable = results->cpuc_state_change_enable;
-+ if (mode_data->number_of_displays > 1) {
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (gtn(results->stutter_exit_watermark[i],
-+ results->cursor_latency_hiding[i])) {
-+ results->stutter_mode_enable = false;
-+ }
-+ }
-+ }
-+ }
-+ results->dmifdram_access_efficiency =
-+ bw_min(
-+ bw_div(
-+ bw_div(
-+ results->total_display_reads_required_dram_access_data,
-+ results->dram_bandwidth),
-+ results->dmif_total_page_close_open_time),
-+ int_to_fixed(1));
-+ if (gtn(results->total_display_writes_required_dram_access_data,
-+ int_to_fixed(0))) {
-+ results->mcifwrdram_access_efficiency =
-+ bw_min(
-+ bw_div(
-+ bw_div(
-+ results->total_display_writes_required_dram_access_data,
-+ results->dram_bandwidth),
-+ results->mcifwr_total_page_close_open_time),
-+ int_to_fixed(1));
-+ } else {
-+ results->mcifwrdram_access_efficiency = int_to_fixed(0);
-+ }
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ results->average_bandwidth_no_compression[i] =
-+ bw_div(
-+ mul(
-+ mul(
-+ bw_div(
-+ mul(
-+ results->source_width_rounded_up_to_chunks[i],
-+ results->bytes_per_pixel[i]),
-+ (bw_div(
-+ results->h_total[i],
-+ results->pixel_rate[i]))),
-+ results->vsr[i]),
-+ results->bytes_per_request[i]),
-+ results->useful_bytes_per_request[i]);
-+ results->average_bandwidth[i] = bw_div(
-+ results->average_bandwidth_no_compression[i],
-+ results->compression_rate[i]);
-+ }
-+ }
-+ results->total_average_bandwidth_no_compression = int_to_fixed(0);
-+ results->total_average_bandwidth = int_to_fixed(0);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ results->total_average_bandwidth_no_compression = add(
-+ results->total_average_bandwidth_no_compression,
-+ results->average_bandwidth_no_compression[i]);
-+ results->total_average_bandwidth = add(
-+ results->total_average_bandwidth,
-+ results->average_bandwidth[i]);
-+ }
-+ }
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ results->stutter_cycle_duration[i] =
-+ sub(
-+ mul(
-+ bw_div(
-+ bw_div(
-+ mul(
-+ bw_div(
-+ bw_div(
-+ results->adjusted_data_buffer_size[i],
-+ results->bytes_per_pixel[i]),
-+ results->source_width_rounded_up_to_chunks[i]),
-+ results->h_total[i]),
-+ results->vsr[i]),
-+ results->pixel_rate[i]),
-+ results->compression_rate[i]),
-+ bw_max(int_to_fixed(0),
-+ sub(
-+ results->stutter_exit_watermark[i],
-+ bw_div(
-+ mul(
-+ (add(
-+ results->line_buffer_prefetch[i],
-+ int_to_fixed(
-+ 2))),
-+ results->h_total[i]),
-+ results->pixel_rate[i]))));
-+ }
-+ }
-+ results->total_stutter_cycle_duration = int_to_fixed(9999);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ if (gtn(results->total_stutter_cycle_duration,
-+ results->stutter_cycle_duration[i])) {
-+ results->total_stutter_cycle_duration =
-+ results->stutter_cycle_duration[i];
-+ }
-+ }
-+ }
-+ results->stutter_burst_time = bw_div(
-+ mul(results->total_stutter_cycle_duration,
-+ results->total_average_bandwidth),
-+ bw_min(
-+ (mul(results->dram_bandwidth,
-+ results->dmifdram_access_efficiency)),
-+ mul(sclk[sclk_level], vbios->data_return_bus_width)));
-+ results->time_in_self_refresh = sub(
-+ sub(results->total_stutter_cycle_duration,
-+ vbios->stutter_self_refresh_exit_latency),
-+ results->stutter_burst_time);
-+ if (mode_data->d1_display_write_back_dwb_enable == true) {
-+ results->stutter_efficiency = int_to_fixed(0);
-+ } else if (ltn(results->time_in_self_refresh, int_to_fixed(0))) {
-+ results->stutter_efficiency = int_to_fixed(0);
-+ } else {
-+ results->stutter_efficiency = mul(
-+ bw_div(results->time_in_self_refresh,
-+ results->total_stutter_cycle_duration),
-+ int_to_fixed(100));
-+ }
-+ results->worst_number_of_trips_to_memory = int_to_fixed(1);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]
-+ && results->scatter_gather_enable_for_pipe[i] == true) {
-+ results->number_of_trips_to_memory_for_getting_apte_row[i] =
-+ bw_ceil(
-+ bw_div(
-+ results->scatter_gather_pte_requests_in_row[i],
-+ results->scatter_gather_pte_request_limit[i]),
-+ int_to_fixed(1));
-+ if (ltn(results->worst_number_of_trips_to_memory,
-+ results->number_of_trips_to_memory_for_getting_apte_row[i])) {
-+ results->worst_number_of_trips_to_memory =
-+ results->number_of_trips_to_memory_for_getting_apte_row[i];
-+ }
-+ }
-+ }
-+ results->immediate_flip_time = mul(
-+ results->worst_number_of_trips_to_memory,
-+ results->total_dmifmc_urgent_latency);
-+ results->latency_for_non_dmif_clients = add(
-+ results->total_dmifmc_urgent_latency,
-+ results->dmif_burst_time[y_clk_level][sclk_level]);
-+ if (mode_data->d1_display_write_back_dwb_enable == true) {
-+ results->latency_for_non_mcifwr_clients = add(
-+ vbios->mcifwrmc_urgent_latency,
-+ dceip->mcifwr_all_surfaces_burst_time);
-+ } else {
-+ results->latency_for_non_mcifwr_clients = int_to_fixed(0);
-+ }
-+ results->dmifmc_urgent_latency_supported_in_high_sclk_and_yclk = bw_div(
-+ (sub(results->min_read_buffer_size_in_time,
-+ results->dmif_burst_time[high][high])),
-+ results->total_dmifmc_urgent_trips);
-+ results->nbp_state_dram_speed_change_margin = int_to_fixed(9999);
-+ for (i = 0; i <= maximum_number_of_surfaces - 1; i += 1) {
-+ if (results->enable[i]) {
-+ results->nbp_state_dram_speed_change_margin =
-+ bw_min(
-+ results->nbp_state_dram_speed_change_margin,
-+ sub(
-+ results->maximum_latency_hiding_with_cursor[i],
-+ results->nbp_state_change_watermark[i]));
-+ }
-+ }
-+ for (i = 1; i <= 5; i += 1) {
-+ results->display_reads_time_for_data_transfer_and_urgent_latency =
-+ sub(results->min_read_buffer_size_in_time,
-+ mul(results->total_dmifmc_urgent_trips,
-+ int_to_fixed(i)));
-+ if (pipe_check == def_ok
-+ && (gtn(
-+ results->display_reads_time_for_data_transfer_and_urgent_latency,
-+ results->dmif_total_page_close_open_time))) {
-+ results->dmif_required_sclk_for_urgent_latency[i] =
-+ bw_div(
-+ bw_div(
-+ results->total_display_reads_required_data,
-+ results->display_reads_time_for_data_transfer_and_urgent_latency),
-+ vbios->data_return_bus_width);
-+ } else {
-+ results->dmif_required_sclk_for_urgent_latency[i] =
-+ int_to_fixed(0);
-+ }
-+ }
-+
-+}
-+
-+/*******************************************************************************
-+ * Public functions
-+ ******************************************************************************/
-+
-+void bw_calcs_init(struct bw_calcs_input_dceip *bw_dceip,
-+ struct bw_calcs_input_vbios *bw_vbios)
-+{
-+ struct bw_calcs_input_dceip dceip;
-+ struct bw_calcs_input_vbios vbios;
-+
-+ vbios.number_of_dram_channels = int_to_fixed(2);
-+ vbios.dram_channel_width_in_bits = int_to_fixed(64);
-+ vbios.number_of_dram_banks = int_to_fixed(8);
-+ vbios.high_yclk = int_to_fixed(1600);
-+ vbios.low_yclk = frc_to_fixed(66666, 100);
-+ vbios.low_sclk = int_to_fixed(200);
-+ vbios.mid_sclk = int_to_fixed(300);
-+ vbios.high_sclk = frc_to_fixed(62609, 100);
-+ vbios.low_voltage_max_dispclk = int_to_fixed(352);
-+ vbios.mid_voltage_max_dispclk = int_to_fixed(467);
-+ vbios.high_voltage_max_dispclk = int_to_fixed(643);
-+ vbios.data_return_bus_width = int_to_fixed(32);
-+ vbios.trc = int_to_fixed(50);
-+ vbios.dmifmc_urgent_latency = int_to_fixed(4);
-+ vbios.stutter_self_refresh_exit_latency = frc_to_fixed(153, 10);
-+ vbios.nbp_state_change_latency = frc_to_fixed(19649, 1000);
-+ vbios.mcifwrmc_urgent_latency = int_to_fixed(10);
-+ vbios.scatter_gather_enable = true;
-+ vbios.down_spread_percentage = frc_to_fixed(5, 10);
-+ vbios.cursor_width = int_to_fixed(32);
-+ vbios.average_compression_rate = int_to_fixed(4);
-+ vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel =
-+ int_to_fixed(256);
-+ vbios.blackout_duration = int_to_fixed(18); /* us */
-+ vbios.maximum_blackout_recovery_time = int_to_fixed(20);
-+ dceip.dmif_request_buffer_size = int_to_fixed(768);
-+ dceip.de_tiling_buffer = int_to_fixed(0);
-+ dceip.dcfclk_request_generation = int_to_fixed(0);
-+ dceip.lines_interleaved_into_lb = int_to_fixed(2);
-+ dceip.chunk_width = int_to_fixed(256);
-+ dceip.number_of_graphics_pipes = int_to_fixed(3);
-+ dceip.number_of_underlay_pipes = int_to_fixed(1);
-+ dceip.display_write_back_supported = false;
-+ dceip.argb_compression_support = false;
-+ dceip.underlay_vscaler_efficiency6_bit_per_component = frc_to_fixed(
-+ 35556, 10000);
-+ dceip.underlay_vscaler_efficiency8_bit_per_component = frc_to_fixed(
-+ 34286, 10000);
-+ dceip.underlay_vscaler_efficiency10_bit_per_component = frc_to_fixed(32,
-+ 10);
-+ dceip.underlay_vscaler_efficiency12_bit_per_component = int_to_fixed(3);
-+ dceip.graphics_vscaler_efficiency6_bit_per_component = frc_to_fixed(35,
-+ 10);
-+ dceip.graphics_vscaler_efficiency8_bit_per_component = frc_to_fixed(
-+ 34286, 10000);
-+ dceip.graphics_vscaler_efficiency10_bit_per_component = frc_to_fixed(32,
-+ 10);
-+ dceip.graphics_vscaler_efficiency12_bit_per_component = int_to_fixed(3);
-+ dceip.alpha_vscaler_efficiency = int_to_fixed(3);
-+ dceip.max_dmif_buffer_allocated = int_to_fixed(2);
-+ dceip.graphics_dmif_size = int_to_fixed(12288);
-+ dceip.underlay_luma_dmif_size = int_to_fixed(19456);
-+ dceip.underlay_chroma_dmif_size = int_to_fixed(23552);
-+ dceip.pre_downscaler_enabled = true;
-+ dceip.underlay_downscale_prefetch_enabled = true;
-+ dceip.lb_write_pixels_per_dispclk = int_to_fixed(1);
-+ dceip.lb_size_per_component444 = int_to_fixed(82176);
-+ dceip.graphics_lb_nodownscaling_multi_line_prefetching = false;
-+ dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
-+ int_to_fixed(0);
-+ dceip.underlay420_luma_lb_size_per_component = int_to_fixed(82176);
-+ dceip.underlay420_chroma_lb_size_per_component = int_to_fixed(164352);
-+ dceip.underlay422_lb_size_per_component = int_to_fixed(82176);
-+ dceip.cursor_chunk_width = int_to_fixed(64);
-+ dceip.cursor_dcp_buffer_lines = int_to_fixed(4);
-+ dceip.cursor_memory_interface_buffer_pixels = int_to_fixed(64);
-+ dceip.underlay_maximum_width_efficient_for_tiling = int_to_fixed(1920);
-+ dceip.underlay_maximum_height_efficient_for_tiling = int_to_fixed(1080);
-+ dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
-+ frc_to_fixed(3, 10);
-+ dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
-+ int_to_fixed(25);
-+ dceip.minimum_outstanding_pte_request_limit = int_to_fixed(2);
-+ dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
-+ int_to_fixed(128);
-+ dceip.limit_excessive_outstanding_dmif_requests = true;
-+ dceip.linear_mode_line_request_alternation_slice = int_to_fixed(64);
-+ dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
-+ int_to_fixed(32);
-+ dceip.display_write_back420_luma_mcifwr_buffer_size = int_to_fixed(
-+ 12288);
-+ dceip.display_write_back420_chroma_mcifwr_buffer_size = int_to_fixed(
-+ 8192);
-+ dceip.request_efficiency = frc_to_fixed(8, 10);
-+ dceip.dispclk_per_request = int_to_fixed(2);
-+ dceip.dispclk_ramping_factor = frc_to_fixed(11, 10);
-+ dceip.display_pipe_throughput_factor = frc_to_fixed(105, 100);
-+ dceip.scatter_gather_pte_request_rows_in_tiling_mode = int_to_fixed(2);
-+ dceip.mcifwr_all_surfaces_burst_time = int_to_fixed(0); /* todo: this is a bug*/
-+
-+ *bw_dceip = dceip;
-+ *bw_vbios = vbios;
-+}
-+
-+/**
-+ * Return:
-+ * true - Display(s) configuration supported.
-+ * In this case 'calcs_output' contains data for HW programming
-+ * false - Display(s) configuration not supported (not enough bandwidth).
-+ */
-+
-+bool bw_calcs(struct dc_context *ctx, const struct bw_calcs_input_dceip *dceip,
-+ const struct bw_calcs_input_vbios *vbios,
-+ const struct bw_calcs_input_mode_data *mode_data,
-+ struct bw_calcs_output *calcs_output)
-+{
-+ struct bw_results_internal *bw_results_internal = dc_service_alloc(
-+ ctx, sizeof(struct bw_results_internal));
-+ struct bw_calcs_input_mode_data_internal *bw_data_internal =
-+ dc_service_alloc(
-+ ctx, sizeof(struct bw_calcs_input_mode_data_internal));
-+ switch (mode_data->number_of_displays) {
-+ case (3):
-+ bw_data_internal->d2_htotal = int_to_fixed(
-+ mode_data->displays_data[2].h_total);
-+ bw_data_internal->d2_pixel_rate =
-+ mode_data->displays_data[2].pixel_rate;
-+ bw_data_internal->d2_graphics_src_width = int_to_fixed(
-+ mode_data->displays_data[2].graphics_src_width);
-+ bw_data_internal->d2_graphics_src_height = int_to_fixed(
-+ mode_data->displays_data[2].graphics_src_height);
-+ bw_data_internal->d2_graphics_scale_ratio =
-+ mode_data->displays_data[2].graphics_scale_ratio;
-+ bw_data_internal->d2_graphics_stereo_mode =
-+ mode_data->displays_data[2].graphics_stereo_mode;
-+ case (2):
-+ bw_data_internal->d1_display_write_back_dwb_enable = false;
-+ bw_data_internal->d1_underlay_mode = ul_none;
-+ bw_data_internal->d1_underlay_scale_ratio = int_to_fixed(0);
-+ bw_data_internal->d1_htotal = int_to_fixed(
-+ mode_data->displays_data[1].h_total);
-+ bw_data_internal->d1_pixel_rate =
-+ mode_data->displays_data[1].pixel_rate;
-+ bw_data_internal->d1_graphics_src_width = int_to_fixed(
-+ mode_data->displays_data[1].graphics_src_width);
-+ bw_data_internal->d1_graphics_src_height = int_to_fixed(
-+ mode_data->displays_data[1].graphics_src_height);
-+ bw_data_internal->d1_graphics_scale_ratio =
-+ mode_data->displays_data[1].graphics_scale_ratio;
-+ bw_data_internal->d1_graphics_stereo_mode =
-+ mode_data->displays_data[1].graphics_stereo_mode;
-+
-+ case (1):
-+ bw_data_internal->d0_fbc_enable =
-+ mode_data->displays_data[0].fbc_enable;
-+ bw_data_internal->d0_lpt_enable =
-+ mode_data->displays_data[0].lpt_enable;
-+ bw_data_internal->d0_underlay_mode =
-+ mode_data->displays_data[0].underlay_mode;
-+ bw_data_internal->d0_underlay_scale_ratio = int_to_fixed(0);
-+ bw_data_internal->d0_htotal = int_to_fixed(
-+ mode_data->displays_data[0].h_total);
-+ bw_data_internal->d0_pixel_rate =
-+ mode_data->displays_data[0].pixel_rate;
-+ bw_data_internal->d0_graphics_src_width = int_to_fixed(
-+ mode_data->displays_data[0].graphics_src_width);
-+ bw_data_internal->d0_graphics_src_height = int_to_fixed(
-+ mode_data->displays_data[0].graphics_src_height);
-+ bw_data_internal->d0_graphics_scale_ratio =
-+ mode_data->displays_data[0].graphics_scale_ratio;
-+ bw_data_internal->d0_graphics_stereo_mode =
-+ mode_data->displays_data[0].graphics_stereo_mode;
-+
-+ default:
-+ /* data for all displays */
-+ bw_data_internal->number_of_displays =
-+ mode_data->number_of_displays;
-+ bw_data_internal->graphics_rotation_angle = int_to_fixed(
-+ mode_data->displays_data[0].graphics_rotation_angle);
-+ bw_data_internal->underlay_rotation_angle = int_to_fixed(
-+ mode_data->displays_data[0].underlay_rotation_angle);
-+ bw_data_internal->underlay_surface_type =
-+ mode_data->displays_data[0].underlay_surface_type;
-+ bw_data_internal->panning_and_bezel_adjustment =
-+ mode_data->displays_data[0].panning_and_bezel_adjustment;
-+ bw_data_internal->graphics_tiling_mode =
-+ mode_data->displays_data[0].graphics_tiling_mode;
-+ bw_data_internal->graphics_interlace_mode =
-+ mode_data->displays_data[0].graphics_interlace_mode;
-+ bw_data_internal->graphics_bytes_per_pixel = int_to_fixed(
-+ mode_data->displays_data[0].graphics_bytes_per_pixel);
-+ bw_data_internal->graphics_htaps = int_to_fixed(
-+ mode_data->displays_data[0].graphics_h_taps);
-+ bw_data_internal->graphics_vtaps = int_to_fixed(
-+ mode_data->displays_data[0].graphics_v_taps);
-+ bw_data_internal->graphics_lb_bpc = int_to_fixed(
-+ mode_data->displays_data[0].graphics_lb_bpc);
-+ bw_data_internal->underlay_lb_bpc = int_to_fixed(
-+ mode_data->displays_data[0].underlay_lb_bpc);
-+ bw_data_internal->underlay_tiling_mode =
-+ mode_data->displays_data[0].underlay_tiling_mode;
-+ bw_data_internal->underlay_htaps = int_to_fixed(
-+ mode_data->displays_data[0].underlay_h_taps);
-+ bw_data_internal->underlay_vtaps = int_to_fixed(
-+ mode_data->displays_data[0].underlay_v_taps);
-+ bw_data_internal->underlay_src_width = int_to_fixed(
-+ mode_data->displays_data[0].underlay_src_width);
-+ bw_data_internal->underlay_src_height = int_to_fixed(
-+ mode_data->displays_data[0].underlay_src_height);
-+ bw_data_internal->underlay_pitch_in_pixels = int_to_fixed(
-+ mode_data->displays_data[0].underlay_pitch_in_pixels);
-+ bw_data_internal->underlay_stereo_mode =
-+ mode_data->displays_data[0].underlay_stereo_mode;
-+ bw_data_internal->display_synchronization_enabled =
-+ mode_data->display_synchronization_enabled;
-+ }
-+
-+ if (bw_data_internal->number_of_displays != 0) {
-+ struct bw_fixed high_sclk = vbios->high_sclk;
-+ struct bw_fixed low_sclk = vbios->low_sclk;
-+ struct bw_fixed high_yclk = vbios->high_yclk;
-+ struct bw_fixed low_yclk = vbios->low_yclk;
-+
-+ ((struct bw_calcs_input_vbios *)vbios)->low_yclk = low_yclk;
-+ ((struct bw_calcs_input_vbios *)vbios)->high_yclk = low_yclk;
-+ ((struct bw_calcs_input_vbios *)vbios)->low_sclk = low_sclk;
-+ ((struct bw_calcs_input_vbios *)vbios)->mid_sclk = low_sclk;
-+ ((struct bw_calcs_input_vbios *)vbios)->high_sclk = low_sclk;
-+ calculate_bandwidth(dceip, vbios, bw_data_internal,
-+ bw_results_internal);
-+
-+ /* units: nanosecond, 16bit storage. */
-+ calcs_output->nbp_state_change_watermark[0].b_mark =
-+ mul(bw_results_internal->nbp_state_change_watermark[4],
-+ int_to_fixed(1000)).value >> 24;
-+ calcs_output->nbp_state_change_watermark[1].b_mark =
-+ mul(bw_results_internal->nbp_state_change_watermark[5],
-+ int_to_fixed(1000)).value >> 24;
-+ calcs_output->nbp_state_change_watermark[2].b_mark =
-+ mul(bw_results_internal->nbp_state_change_watermark[6],
-+ int_to_fixed(1000)).value >> 24;
-+
-+ calcs_output->stutter_exit_watermark[0].b_mark =
-+ mul(bw_results_internal->stutter_exit_watermark[4],
-+ int_to_fixed(1000)).value >> 24;
-+ calcs_output->stutter_exit_watermark[1].b_mark =
-+ mul(bw_results_internal->stutter_exit_watermark[5],
-+ int_to_fixed(1000)).value >> 24;
-+ calcs_output->stutter_exit_watermark[2].b_mark =
-+ mul(bw_results_internal->stutter_exit_watermark[6],
-+ int_to_fixed(1000)).value >> 24;
-+
-+ calcs_output->urgent_watermark[0].b_mark =
-+ mul(bw_results_internal->urgent_watermark[4],
-+ int_to_fixed(1000)).value >> 24;
-+ calcs_output->urgent_watermark[1].b_mark =
-+ mul(bw_results_internal->urgent_watermark[5],
-+ int_to_fixed(1000)).value >> 24;
-+ calcs_output->urgent_watermark[2].b_mark =
-+ mul(bw_results_internal->urgent_watermark[6],
-+ int_to_fixed(1000)).value >> 24;
-+
-+ ((struct bw_calcs_input_vbios *)vbios)->low_yclk = high_yclk;
-+ ((struct bw_calcs_input_vbios *)vbios)->high_yclk = high_yclk;
-+ ((struct bw_calcs_input_vbios *)vbios)->low_sclk = high_sclk;
-+ ((struct bw_calcs_input_vbios *)vbios)->mid_sclk = high_sclk;
-+ ((struct bw_calcs_input_vbios *)vbios)->high_sclk = high_sclk;
-+
-+ calculate_bandwidth(dceip, vbios, bw_data_internal,
-+ bw_results_internal);
-+
-+ calcs_output->nbp_state_change_watermark[0].a_mark =
-+ mul(bw_results_internal->nbp_state_change_watermark[4],
-+ int_to_fixed(1000)).value >> 24;
-+ calcs_output->nbp_state_change_watermark[1].a_mark =
-+ mul(bw_results_internal->nbp_state_change_watermark[5],
-+ int_to_fixed(1000)).value >> 24;
-+ calcs_output->nbp_state_change_watermark[2].a_mark =
-+ mul(bw_results_internal->nbp_state_change_watermark[6],
-+ int_to_fixed(1000)).value >> 24;
-+
-+ calcs_output->stutter_exit_watermark[0].a_mark =
-+ mul(bw_results_internal->stutter_exit_watermark[4],
-+ int_to_fixed(1000)).value >> 24;
-+ calcs_output->stutter_exit_watermark[1].a_mark =
-+ mul(bw_results_internal->stutter_exit_watermark[5],
-+ int_to_fixed(1000)).value >> 24;
-+ calcs_output->stutter_exit_watermark[2].a_mark =
-+ mul(bw_results_internal->stutter_exit_watermark[6],
-+ int_to_fixed(1000)).value >> 24;
-+
-+ calcs_output->urgent_watermark[0].a_mark =
-+ mul(bw_results_internal->urgent_watermark[4],
-+ int_to_fixed(1000)).value >> 24;
-+ calcs_output->urgent_watermark[1].a_mark =
-+ mul(bw_results_internal->urgent_watermark[5],
-+ int_to_fixed(1000)).value >> 24;
-+ calcs_output->urgent_watermark[2].a_mark =
-+ mul(bw_results_internal->urgent_watermark[6],
-+ int_to_fixed(1000)).value >> 24;
-+
-+ calcs_output->nbp_state_change_enable =
-+ bw_results_internal->nbp_state_change_enable;
-+ calcs_output->cpuc_state_change_enable =
-+ bw_results_internal->cpuc_state_change_enable;
-+ calcs_output->cpup_state_change_enable =
-+ bw_results_internal->cpup_state_change_enable;
-+ calcs_output->stutter_mode_enable =
-+ bw_results_internal->stutter_mode_enable;
-+ calcs_output->dispclk =
-+ mul(bw_results_internal->dispclk,
-+ int_to_fixed(1000)).value >> 24;
-+ calcs_output->required_sclk =
-+ mul(bw_results_internal->required_sclk,
-+ int_to_fixed(1000)).value >> 24;
-+
-+ ((struct bw_calcs_input_vbios *)vbios)->low_yclk = low_yclk;
-+ ((struct bw_calcs_input_vbios *)vbios)->high_yclk = high_yclk;
-+ ((struct bw_calcs_input_vbios *)vbios)->low_sclk = low_sclk;
-+ ((struct bw_calcs_input_vbios *)vbios)->mid_sclk = high_sclk;
-+ ((struct bw_calcs_input_vbios *)vbios)->high_sclk = high_sclk;
-+ } else {
-+ calcs_output->nbp_state_change_enable = true;
-+ calcs_output->cpuc_state_change_enable = true;
-+ calcs_output->cpup_state_change_enable = true;
-+ calcs_output->stutter_mode_enable = true;
-+ calcs_output->dispclk = 0;
-+ calcs_output->required_sclk = 0;
-+ }
-+
-+ dc_service_free(ctx, bw_data_internal);
-+ dc_service_free(ctx, bw_results_internal);
-+ return true;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/calcs/bw_fixed.c b/drivers/gpu/drm/amd/dal/dc/calcs/bw_fixed.c
-new file mode 100644
-index 0000000..6bad7c6
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/calcs/bw_fixed.c
-@@ -0,0 +1,278 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#include "dc_services.h"
-+#include "bw_fixed.h"
-+
-+
-+#define BITS_PER_FRACTIONAL_PART 24
-+
-+#define MIN_I32 \
-+ (long long)(-(1LL << (63 - BITS_PER_FRACTIONAL_PART)))
-+
-+#define MAX_I32 \
-+ (long long)((1ULL << (63 - BITS_PER_FRACTIONAL_PART)) - 1)
-+
-+#define MIN_I64 \
-+ (long long)(-(1LL << 63))
-+
-+#define MAX_I64 \
-+ (long long)((1ULL << 63) - 1)
-+
-+
-+#define FRACTIONAL_PART_MASK \
-+ ((1ULL << BITS_PER_FRACTIONAL_PART) - 1)
-+
-+#define GET_INTEGER_PART(x) \
-+ ((x) >> BITS_PER_FRACTIONAL_PART)
-+
-+#define GET_FRACTIONAL_PART(x) \
-+ (FRACTIONAL_PART_MASK & (x))
-+
-+static unsigned long long abs_i64(long long arg)
-+{
-+ if (arg >= 0)
-+ return (unsigned long long)(arg);
-+ else
-+ return (unsigned long long)(-arg);
-+}
-+
-+struct bw_fixed bw_min3(struct bw_fixed v1, struct bw_fixed v2, struct bw_fixed v3)
-+{
-+ return bw_min(bw_min(v1, v2), v3);
-+}
-+
-+struct bw_fixed bw_max3(struct bw_fixed v1, struct bw_fixed v2, struct bw_fixed v3)
-+{
-+ return bw_max(bw_max(v1, v2), v3);
-+}
-+
-+struct bw_fixed int_to_fixed(long long value)
-+{
-+ struct bw_fixed res;
-+ ASSERT(value < MAX_I32 && value > MIN_I32);
-+ res.value = value << BITS_PER_FRACTIONAL_PART;
-+ return res;
-+}
-+
-+struct bw_fixed frc_to_fixed(long long numerator, long long denominator)
-+{
-+ struct bw_fixed res;
-+ bool arg1_negative = numerator < 0;
-+ bool arg2_negative = denominator < 0;
-+ unsigned long long arg1_value;
-+ unsigned long long arg2_value;
-+ unsigned long long remainder;
-+
-+ /* determine integer part */
-+ unsigned long long res_value;
-+
-+ ASSERT(denominator != 0);
-+
-+ arg1_value = abs_i64(numerator);
-+ arg2_value = abs_i64(denominator);
-+ remainder = arg1_value % arg2_value;
-+ res_value = arg1_value / arg2_value;
-+
-+ ASSERT(res_value <= MAX_I32);
-+
-+ /* determine fractional part */
-+ {
-+ unsigned int i = BITS_PER_FRACTIONAL_PART;
-+
-+ do
-+ {
-+ remainder <<= 1;
-+
-+ res_value <<= 1;
-+
-+ if (remainder >= arg2_value)
-+ {
-+ res_value |= 1;
-+ remainder -= arg2_value;
-+ }
-+ } while (--i != 0);
-+ }
-+
-+ /* round up LSB */
-+ {
-+ unsigned long long summand = (remainder << 1) >= arg2_value;
-+
-+ ASSERT(res_value <= MAX_I64 - summand);
-+
-+ res_value += summand;
-+ }
-+
-+ res.value = (signed long long)(res_value);
-+
-+ if (arg1_negative ^ arg2_negative)
-+ res.value = -res.value;
-+ return res;
-+}
-+
-+struct bw_fixed bw_min(const struct bw_fixed arg1, const struct bw_fixed arg2)
-+{
-+ return (arg1.value <= arg2.value) ? arg1 : arg2;
-+}
-+
-+struct bw_fixed bw_max(const struct bw_fixed arg1, const struct bw_fixed arg2)
-+{
-+ return (arg2.value <= arg1.value) ? arg1 : arg2;
-+}
-+
-+struct bw_fixed bw_floor(const struct bw_fixed arg, const struct bw_fixed significance)
-+{
-+ struct bw_fixed result;
-+ signed long long multiplicand = arg.value / abs_i64(significance.value);
-+ result.value = abs_i64(significance.value) * multiplicand;
-+ ASSERT(abs_i64(result.value) <= abs_i64(arg.value));
-+ return result;
-+}
-+
-+struct bw_fixed bw_ceil(const struct bw_fixed arg, const struct bw_fixed significance)
-+{
-+ struct bw_fixed result;
-+ result.value = arg.value + arg.value % abs_i64(significance.value);
-+ if (result.value < significance.value)
-+ result.value = significance.value;
-+ return result;
-+}
-+
-+struct bw_fixed add(const struct bw_fixed arg1, const struct bw_fixed arg2)
-+{
-+ struct bw_fixed res;
-+
-+ res.value = arg1.value + arg2.value;
-+
-+ return res;
-+}
-+
-+struct bw_fixed sub(const struct bw_fixed arg1, const struct bw_fixed arg2)
-+{
-+ struct bw_fixed res;
-+
-+ res.value = arg1.value - arg2.value;
-+
-+ return res;
-+}
-+
-+struct bw_fixed mul(const struct bw_fixed arg1, const struct bw_fixed arg2)
-+{
-+ struct bw_fixed res;
-+
-+ bool arg1_negative = arg1.value < 0;
-+ bool arg2_negative = arg2.value < 0;
-+
-+ unsigned long long arg1_value = abs_i64(arg1.value);
-+ unsigned long long arg2_value = abs_i64(arg2.value);
-+
-+ unsigned long long arg1_int = GET_INTEGER_PART(arg1_value);
-+ unsigned long long arg2_int = GET_INTEGER_PART(arg2_value);
-+
-+ unsigned long long arg1_fra = GET_FRACTIONAL_PART(arg1_value);
-+ unsigned long long arg2_fra = GET_FRACTIONAL_PART(arg2_value);
-+
-+ unsigned long long tmp;
-+
-+ res.value = arg1_int * arg2_int;
-+
-+ ASSERT(res.value <= MAX_I32);
-+
-+ res.value <<= BITS_PER_FRACTIONAL_PART;
-+
-+ tmp = arg1_int * arg2_fra;
-+
-+ ASSERT(tmp <= (unsigned long long)(MAX_I64 - res.value));
-+
-+ res.value += tmp;
-+
-+ tmp = arg2_int * arg1_fra;
-+
-+ ASSERT(tmp <= (unsigned long long)(MAX_I64 - res.value));
-+
-+ res.value += tmp;
-+
-+ tmp = arg1_fra * arg2_fra;
-+
-+ tmp = (tmp >> BITS_PER_FRACTIONAL_PART) +
-+ (tmp >= (unsigned long long)(frc_to_fixed(1, 2).value));
-+
-+ ASSERT(tmp <= (unsigned long long)(MAX_I64 - res.value));
-+
-+ res.value += tmp;
-+
-+ if (arg1_negative ^ arg2_negative)
-+ res.value = -res.value;
-+ return res;
-+}
-+
-+struct bw_fixed bw_div(const struct bw_fixed arg1, const struct bw_fixed arg2)
-+{
-+ struct bw_fixed res = frc_to_fixed(arg1.value, arg2.value);
-+ return res;
-+}
-+
-+struct bw_fixed fixed31_32_to_bw_fixed(long long raw)
-+{
-+ struct bw_fixed result = { 0 };
-+
-+ if (raw < 0) {
-+ raw = -raw;
-+ result.value = -(raw >> (32 - BITS_PER_FRACTIONAL_PART));
-+ } else {
-+ result.value = raw >> (32 - BITS_PER_FRACTIONAL_PART);
-+ }
-+
-+ return result;
-+}
-+
-+bool equ(const struct bw_fixed arg1, const struct bw_fixed arg2)
-+{
-+ return arg1.value == arg2.value;
-+}
-+
-+bool neq(const struct bw_fixed arg1, const struct bw_fixed arg2)
-+{
-+ return arg1.value != arg2.value;
-+}
-+
-+bool leq(const struct bw_fixed arg1, const struct bw_fixed arg2)
-+{
-+ return arg1.value <= arg2.value;
-+}
-+
-+bool geq(const struct bw_fixed arg1, const struct bw_fixed arg2)
-+{
-+ return arg1.value >= arg2.value;
-+}
-+
-+bool ltn(const struct bw_fixed arg1, const struct bw_fixed arg2)
-+{
-+ return arg1.value < arg2.value;
-+}
-+
-+bool gtn(const struct bw_fixed arg1, const struct bw_fixed arg2)
-+{
-+ return arg1.value > arg2.value;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/calcs/scaler_filter.c b/drivers/gpu/drm/amd/dal/dc/calcs/scaler_filter.c
-new file mode 100644
-index 0000000..f8ee65e
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/calcs/scaler_filter.c
-@@ -0,0 +1,1992 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/fixed31_32.h"
-+
-+#include "scaler_filter.h"
-+
-+enum {
-+ DOWN_DB_SCALES = 8,
-+ DOWN_DB_POINTS = 11,
-+
-+ UP_DB_SCALES = 1,
-+ UP_DB_POINTS = 7,
-+
-+ MIN_SHARPNESS = -50,
-+ MAX_SHARPNESS = 50,
-+
-+ CONST_DIVIDER = 10000000,
-+
-+ MAX_HOR_DOWNSCALE = 1666000, /* 1:6 */
-+ MAX_VER_DOWNSCALE = 1666000, /* 1:6 */
-+
-+ MAX_HOR_UPSCALE = 160000000, /* 16:1 */
-+ MAX_VER_UPSCALE = 160000000, /* 16:1 */
-+
-+ THRESHOLDRATIOLOW = 8000000, /* 0.8 */
-+ THRESHOLDRATIOUP = 10000000, /* 1.0 */
-+
-+ DOWN_DB_FUZZY = -120411996, /* -12.041200 */
-+ DOWN_DB_FLAT = -60205998, /* -6.020600 */
-+ DOWN_DB_SHARP = -10000000, /* -1.000000 */
-+
-+ UP_DB_FUZZY = -60205998, /* -6.020600 */
-+ UP_DB_FLAT = 0,
-+ UP_DB_SHARP = 60205998 /* 6.020600 */
-+};
-+
-+static inline struct fixed31_32 max_hor_downscale(void)
-+{
-+ return dal_fixed31_32_from_fraction(MAX_HOR_DOWNSCALE, CONST_DIVIDER);
-+}
-+
-+static inline struct fixed31_32 max_ver_downscale(void)
-+{
-+ return dal_fixed31_32_from_fraction(MAX_VER_DOWNSCALE, CONST_DIVIDER);
-+}
-+
-+static inline struct fixed31_32 max_hor_upscale(void)
-+{
-+ return dal_fixed31_32_from_fraction(MAX_HOR_UPSCALE, CONST_DIVIDER);
-+}
-+
-+static inline struct fixed31_32 max_ver_upscale(void)
-+{
-+ return dal_fixed31_32_from_fraction(MAX_VER_UPSCALE, CONST_DIVIDER);
-+}
-+
-+static inline struct fixed31_32 threshold_ratio_low(void)
-+{
-+ return dal_fixed31_32_from_fraction(THRESHOLDRATIOLOW, CONST_DIVIDER);
-+}
-+
-+static inline struct fixed31_32 threshold_ratio_up(void)
-+{
-+ return dal_fixed31_32_from_fraction(THRESHOLDRATIOUP, CONST_DIVIDER);
-+}
-+
-+static inline struct fixed31_32 down_db_fuzzy(void)
-+{
-+ return dal_fixed31_32_from_fraction(DOWN_DB_FUZZY, CONST_DIVIDER);
-+}
-+
-+static inline struct fixed31_32 down_db_flat(void)
-+{
-+ return dal_fixed31_32_from_fraction(DOWN_DB_FLAT, CONST_DIVIDER);
-+}
-+
-+static inline struct fixed31_32 down_db_sharp(void)
-+{
-+ return dal_fixed31_32_from_fraction(DOWN_DB_SHARP, CONST_DIVIDER);
-+}
-+
-+static inline struct fixed31_32 up_db_fuzzy(void)
-+{
-+ return dal_fixed31_32_from_fraction(UP_DB_FUZZY, CONST_DIVIDER);
-+}
-+
-+static inline struct fixed31_32 up_db_flat(void)
-+{
-+ return dal_fixed31_32_from_fraction(UP_DB_FLAT, CONST_DIVIDER);
-+}
-+
-+static inline struct fixed31_32 up_db_sharp(void)
-+{
-+ return dal_fixed31_32_from_fraction(UP_DB_SHARP, CONST_DIVIDER);
-+}
-+
-+static const int32_t
-+ downscaling_db_table[][DOWN_DB_SCALES + 1][DOWN_DB_POINTS] = {
-+ /* 3 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ {
-+ 14302719, 14302719, 14302719,
-+ 10000000, 99999, 99999,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 14302339, 14302339, 14302339,
-+ 10000000, 4452010, 99999,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 14302760, 14302760, 14302760,
-+ 10000000, 7826979, 5258399,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 14302819, 14302819, 14302819,
-+ 10000000, 8669400, 7414469,
-+ 4422729, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 14302730, 14302730, 12791190,
-+ 10000000, 9045640, 8180170,
-+ 6477950, 4599249, 2019010,
-+ 99999, 99999
-+ },
-+ {
-+ 14302699, 14302699, 12067849,
-+ 10000000, 9236029, 8541280,
-+ 7252740, 6021010, 4820120,
-+ 3511950, 1769340
-+ },
-+ {
-+ 14302710, 14302710, 11783510,
-+ 10000000, 9325690, 8704419,
-+ 7595670, 6583020, 5652850,
-+ 4749999, 3847680
-+ },
-+ {
-+ 14302920, 14302920, 11709250,
-+ 10000000, 9345560, 8754609,
-+ 7692559, 6738259, 5878239,
-+ 5057529, 4264070
-+ }
-+ },
-+ /* 4 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ {
-+ 14308999, 14308999, 14308999,
-+ 10000000, 99999, 99999,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 14308999, 14308999, 14308999,
-+ 10000000, 6311039, 99999,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 14308999, 14308999, 14308999,
-+ 10000000, 8526669, 6832849,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 14308999, 14308999, 12110630,
-+ 10000000, 9117940, 8230940,
-+ 6320130, 3719770, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 14308999, 14308999, 11474980,
-+ 10000000, 9370139, 8771979,
-+ 7601270, 6440780, 5249999,
-+ 3887520, 2039040
-+ },
-+ {
-+ 14308999, 13084859, 11179579,
-+ 10000000, 9495180, 9016919,
-+ 8134520, 7311699, 6560329,
-+ 5845720, 5155519
-+ },
-+ {
-+ 14308999, 12576600, 11048669,
-+ 10000000, 9550499, 9132360,
-+ 8368729, 7679399, 7073119,
-+ 6520900, 6015530
-+ },
-+ {
-+ 14308999, 12448530, 11007410,
-+ 10000000, 9566799, 9165279,
-+ 8435800, 7785279, 7215780,
-+ 6701470, 6240640
-+ }
-+ },
-+ /* 5 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ {
-+ 8971139, 8971139, 8971139,
-+ 10000000, 99999, 99999,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 9466379, 9466379, 9466379,
-+ 10000000, 5648760, 3834280,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 15000000, 15000000, 14550110,
-+ 10000000, 7121120, 5994579,
-+ 4314630, 2606149, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 15000000, 15000000, 13047469,
-+ 10000000, 8368809, 7343569,
-+ 5970299, 4924620, 4029389,
-+ 3171139, 2276369
-+ },
-+ {
-+ 15000000, 14157199, 11897679,
-+ 10000000, 9166659, 8444600,
-+ 7287240, 6374719, 5615460,
-+ 4949580, 4350199
-+ },
-+ {
-+ 15000000, 12877819, 11224579,
-+ 10000000, 9488620, 9016109,
-+ 8203780, 7500000, 6883730,
-+ 6326839, 5818459
-+ },
-+ {
-+ 14733040, 12233200, 10939040,
-+ 10000000, 9608929, 9250000,
-+ 8623390, 8076940, 7606369,
-+ 7177749, 6785169
-+ },
-+ {
-+ 14627330, 12046170, 10862360,
-+ 10000000, 9639260, 9312710,
-+ 8737679, 8242470, 7815709,
-+ 7432209, 7082970
-+ }
-+ },
-+ /* 6 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ {
-+ 8231559, 8231559, 8231559,
-+ 10000000, 99999, 99999,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 8353310, 8353310, 8353310,
-+ 10000000, 5504879, 4310710,
-+ 870359, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 8643479, 8643479, 8643479,
-+ 10000000, 6483510, 5768150,
-+ 4630779, 3580690, 2501940,
-+ 1015309, 99999
-+ },
-+ {
-+ 15000000, 15000000, 13493930,
-+ 10000000, 7516040, 6802409,
-+ 5824409, 5080109, 4454280,
-+ 3896749, 3386510
-+ },
-+ {
-+ 15000000, 14055930, 12321079,
-+ 10000000, 8872389, 8090410,
-+ 7035570, 6281229, 5676810,
-+ 5165010, 4717260
-+ },
-+ {
-+ 15000000, 12915290, 11311399,
-+ 10000000, 9460610, 8988440,
-+ 8202149, 7548679, 6999999,
-+ 6510639, 6065719
-+ },
-+ {
-+ 14310129, 12140829, 10901659,
-+ 10000000, 9635019, 9307180,
-+ 8740929, 8263260, 7858849,
-+ 7499330, 7170130
-+ },
-+ {
-+ 13815449, 11911309, 10801299,
-+ 10000000, 9669629, 9380580,
-+ 8878319, 8452050, 8097199,
-+ 7785030, 7504299
-+ }
-+ },
-+ /* 7 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ {
-+ 10616660, 10616660, 10616660,
-+ 10000000, 2646020, 99999,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 10099999, 10099999, 10099999,
-+ 10000000, 4936839, 4112670,
-+ 2729740, 896539, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 8345860, 8345860, 8345860,
-+ 10000000, 6034079, 5371739,
-+ 4466759, 3763799, 3155870,
-+ 2588019, 2026730
-+ },
-+ {
-+ 9298499, 9298499, 13768420,
-+ 10000000, 7174239, 6524270,
-+ 5670250, 5052099, 4549089,
-+ 4115279, 3722150
-+ },
-+ {
-+ 15000000, 14116940, 12563209,
-+ 10000000, 8542140, 7782419,
-+ 6865050, 6239479, 5758860,
-+ 5351870, 4992800
-+ },
-+ {
-+ 15000000, 12913750, 11306079,
-+ 10000000, 9452580, 8969209,
-+ 8168810, 7538409, 7029479,
-+ 6603180, 6227809
-+ },
-+ {
-+ 14390859, 11862809, 10757420,
-+ 10000000, 9688709, 9404249,
-+ 8904439, 8472480, 8099079,
-+ 7765330, 7459110
-+ },
-+ {
-+ 13752900, 11554559, 10637769,
-+ 10000000, 9736120, 9499999,
-+ 9079759, 8718389, 8408790,
-+ 8134469, 7886120
-+ }
-+ },
-+ /* 8 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ {
-+ 11277090, 11277090, 11277090,
-+ 10000000, 2949059, 99999,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 11196039, 11196039, 11196039,
-+ 10000000, 4627540, 4018869,
-+ 3018769, 2000000, 250770,
-+ 99999, 99999
-+ },
-+ {
-+ 10878369, 10878369, 10878369,
-+ 10000000, 5657230, 5118110,
-+ 4372630, 3809120, 3337709,
-+ 2919510, 2535369
-+ },
-+ {
-+ 9090089, 9090089, 13961290,
-+ 10000000, 6929969, 6334999,
-+ 5569829, 5019649, 4584150,
-+ 4208610, 3876540
-+ },
-+ {
-+ 15000000, 14173229, 12732659,
-+ 10000000, 8267070, 7575380,
-+ 6764540, 6218209, 5803539,
-+ 5454990, 5146239
-+ },
-+ {
-+ 15000000, 12928279, 11292259,
-+ 10000000, 9447429, 8954229,
-+ 8141599, 7516989, 7039459,
-+ 6649519, 6316819
-+ },
-+ {
-+ 14661350, 11638879, 10665880,
-+ 10000000, 9722669, 9464690,
-+ 9013469, 8613470, 8266339,
-+ 7949870, 7663450
-+ },
-+ {
-+ 13861900, 11311980, 10543940,
-+ 10000000, 9772019, 9565100,
-+ 9198870, 8881340, 8609200,
-+ 8365769, 8147500
-+ }
-+ },
-+ /* 9 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ { 10099999, 10099999, 10099999,
-+ 10000000, 2939159, 1526470,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 11726609, 11726609, 11726609,
-+ 10000000, 4329420, 3805609,
-+ 3030480, 2363760, 1732099,
-+ 980139, 99999
-+ },
-+ {
-+ 10949269, 10949269, 10949269,
-+ 10000000, 5452589, 4946640,
-+ 4277969, 3790729, 3392640,
-+ 3048950, 2750000
-+ },
-+ {
-+ 8830279, 8830279, 14084529,
-+ 10000000, 6743149, 6182519,
-+ 5482980, 5000000, 4622060,
-+ 4303340, 4022600
-+ },
-+ {
-+ 9709150, 14111399, 12800760,
-+ 10000000, 7989749, 7445629,
-+ 6741260, 6241980, 5857459,
-+ 5534989, 5255370
-+ },
-+ {
-+ 15000000, 12830289, 11489900,
-+ 10000000, 9302089, 8767340,
-+ 8025540, 7500000, 7100800,
-+ 6768149, 6481850
-+ },
-+ {
-+ 14873609, 11576000, 10650579,
-+ 10000000, 9731360, 9483649,
-+ 9054650, 8680559, 8358049,
-+ 8066400, 7802420
-+ },
-+ {
-+ 12981410, 11185950, 10491620,
-+ 10000000, 9795730, 9611030,
-+ 9286710, 9007279, 8768100,
-+ 8553469, 8361340
-+ }
-+ },
-+ /* 10 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ {
-+ 8993279, 8993279, 8993279,
-+ 10000000, 2921360, 1905619,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 9064850, 9064850, 9064850,
-+ 10000000, 4095619, 3655839,
-+ 3021000, 2500000, 2031680,
-+ 1566990, 1055440
-+ },
-+ {
-+ 11043460, 11043460, 11043460,
-+ 10000000, 5287479, 4816150,
-+ 4208439, 3769229, 3418970,
-+ 3117449, 2850320
-+ },
-+ {
-+ 8651900, 8651900, 14169909,
-+ 10000000, 6596950, 6071490,
-+ 5423219, 4980779, 4644620,
-+ 4362219, 4114899
-+ },
-+ {
-+ 9246050, 14055370, 12832759,
-+ 10000000, 7831320, 7369570,
-+ 6731680, 6262450, 5897690,
-+ 5592269, 5328789
-+ },
-+ {
-+ 15000000, 12770450, 11642129,
-+ 10000000, 9120929, 8601920,
-+ 7946630, 7490440, 7140589,
-+ 6847490, 6593719
-+ },
-+ {
-+ 14062479, 11541219, 10644329,
-+ 10000000, 9736120, 9495139,
-+ 9080520, 8724340, 8419489,
-+ 8146359, 7899820
-+ },
-+ {
-+ 12507469, 11102950, 10457479,
-+ 10000000, 9811149, 9641249,
-+ 9344969, 9090980, 8875219,
-+ 8684499, 8513180
-+ }
-+ },
-+ /* 11 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ {
-+ 10099509, 10099509, 10099509,
-+ 10000000, 2788810, 2054850,
-+ 99999, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 8872069, 8872069, 8872069,
-+ 10000000, 3929649, 3522840,
-+ 2963230, 2527720, 2157579,
-+ 1823610, 1500000
-+ },
-+ {
-+ 10099999, 10099999, 10099999,
-+ 10000000, 5155599, 4712319,
-+ 4154500, 3759450, 3448629,
-+ 3183139, 2948490
-+ },
-+ {
-+ 10511649, 10511649, 14216580,
-+ 10000000, 6445930, 5988820,
-+ 5401239, 4988409, 4673399,
-+ 4410479, 4181599
-+ },
-+ {
-+ 9170889, 14003310, 12949769,
-+ 10000000, 7684900, 7250000,
-+ 6670129, 6255810, 5934680,
-+ 5664110, 5427970
-+ },
-+ {
-+ 15000000, 12763030, 11734730,
-+ 10000000, 8958870, 8478559,
-+ 7893459, 7489529, 7179200,
-+ 6917790, 6688359
-+ },
-+ {
-+ 14634610, 11491880, 10619130,
-+ 10000000, 9744859, 9509819,
-+ 9102900, 8760340, 8463050,
-+ 8202620, 7968729
-+ },
-+ {
-+ 12415319, 10980290, 10405089,
-+ 10000000, 9831910, 9680110,
-+ 9413710, 9184579, 8987190,
-+ 8813819, 8655819
-+ }
-+ },
-+ /* 12 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ {
-+ 10832400, 10832400, 10832400,
-+ 10000000, 2700819, 2115820,
-+ 750000, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 10747549, 10747549, 10747549,
-+ 10000000, 3781630, 3415020,
-+ 2914879, 2537429, 2221180,
-+ 1943199, 1688420
-+ },
-+ {
-+ 11630790, 11630790, 11630790,
-+ 10000000, 5047429, 4631519,
-+ 4113860, 3750000, 3469760,
-+ 3229379, 3016360
-+ },
-+ {
-+ 10780229, 10780229, 10780229,
-+ 10000000, 6340010, 5935009,
-+ 5387600, 4995940, 4695929,
-+ 4446829, 4231610
-+ },
-+ {
-+ 9055669, 13968739, 13037070,
-+ 10000000, 7556660, 7149490,
-+ 6625509, 6250000, 5958870,
-+ 5713790, 5500869
-+ },
-+ {
-+ 14614900, 12760740, 11806739,
-+ 10000000, 8824530, 8388419,
-+ 7857400, 7489010, 7206150,
-+ 6968010, 6759889
-+ },
-+ {
-+ 14894100, 11451840, 10598870,
-+ 10000000, 9750000, 9521099,
-+ 9122239, 8784019, 8494700,
-+ 8243309, 8018680
-+ },
-+ {
-+ 12298769, 10886880, 10367530,
-+ 10000000, 9846829, 9708030,
-+ 9464049, 9252949, 9072539,
-+ 8910980, 8766649
-+ }
-+ },
-+ /* 13 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ {
-+ 10099999, 10099999, 10099999,
-+ 10000000, 2574490, 2099110,
-+ 1194889, 99999, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 10099999, 10099999, 10099999,
-+ 10000000, 3679780, 3332070,
-+ 2869139, 2530030, 2251899,
-+ 2010450, 1793050
-+ },
-+ {
-+ 9306690, 9306690, 9306690,
-+ 10000000, 4964010, 4573009,
-+ 4082309, 3742089, 3481810,
-+ 3262990, 3070969
-+ },
-+ {
-+ 10099999, 10099999, 10099999,
-+ 10000000, 6217889, 5843269,
-+ 5353810, 5000000, 4730190,
-+ 4499999, 4301390
-+ },
-+ {
-+ 8819990, 13964320, 13098440,
-+ 10000000, 7454770, 7075160,
-+ 6591439, 6250000, 5983970,
-+ 5760229, 5564339
-+ },
-+ {
-+ 14432849, 12727780, 11847709,
-+ 10000000, 8695709, 8322049,
-+ 7842620, 7500000, 7234820,
-+ 7010849, 6814730
-+ },
-+ {
-+ 15000000, 11440130, 10620100,
-+ 10000000, 9742270, 9508739,
-+ 9110010, 8782560, 8510140,
-+ 8276290, 8069980
-+ },
-+ {
-+ 12039999, 10825289, 10341939,
-+ 10000000, 9858080, 9729740,
-+ 9505100, 9310669, 9144560,
-+ 8996559, 8862569
-+ }
-+ },
-+ /* 14 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ {
-+ 9289590, 9289590, 9289590,
-+ 10000000, 2485270, 2084970,
-+ 1362659, 250000, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 9484500, 9484500, 9484500,
-+ 10000000, 3593840, 3263100,
-+ 2833609, 2519409, 2267650,
-+ 2050379, 1856749
-+ },
-+ {
-+ 9237130, 9237130, 9237130,
-+ 10000000, 4898909, 4527629,
-+ 4057880, 3734529, 3490320,
-+ 3287230, 3111050
-+ },
-+ {
-+ 9543399, 9543399, 9543399,
-+ 10000000, 6110230, 5772359,
-+ 5328080, 5007240, 4757330,
-+ 4545379, 4359109
-+ },
-+ {
-+ 9032660, 9032660, 9032660,
-+ 10000000, 7373520, 7016940,
-+ 6565740, 6250000, 6002650,
-+ 5794939, 5610830
-+ },
-+ {
-+ 14351329, 12697319, 11875350,
-+ 10000000, 8606730, 8275989,
-+ 7833449, 7510430, 7257339,
-+ 7043970, 6857690
-+ },
-+ {
-+ 13286800, 11436090, 10643019,
-+ 10000000, 9729470, 9491149,
-+ 9096930, 8778640, 8519319,
-+ 8299450, 8104829
-+ },
-+ {
-+ 11838380, 10778709, 10322740,
-+ 10000000, 9866499, 9746059,
-+ 9535790, 9354810, 9200339,
-+ 9063839, 8940430
-+ }
-+ },
-+ /* 15 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ {
-+ 9193199, 9193199, 9193199,
-+ 10000000, 2400999, 2042409,
-+ 1450179, 789309, 99999,
-+ 99999, 99999
-+ },
-+ {
-+ 10755189, 10755189, 10755189,
-+ 10000000, 3532319, 3212479,
-+ 2803660, 2510200, 2278629,
-+ 2078720, 1899970
-+ },
-+ {
-+ 8732669, 8732669, 8732669,
-+ 10000000, 4821290, 4483030,
-+ 4045079, 3737959, 3505080,
-+ 3311960, 3143329
-+ },
-+ {
-+ 9450280, 9450280, 9450280,
-+ 10000000, 6040880, 5718960,
-+ 5302609, 5004199, 4771710,
-+ 4575310, 4404180
-+ },
-+ {
-+ 10520930, 10520930, 10520930,
-+ 10000000, 7298259, 6975160,
-+ 6552690, 6250000, 6018469,
-+ 5822089, 5648869
-+ },
-+ {
-+ 14320160, 12683949, 11917040,
-+ 10000000, 8541300, 8228710,
-+ 7812070, 7509459, 7272909,
-+ 7072560, 6895729
-+ },
-+ {
-+ 15000000, 11434819, 10650700,
-+ 10000000, 9723110, 9480339,
-+ 9083300, 8771640, 8524850,
-+ 8317480, 8135899
-+ },
-+ {
-+ 11750520, 10722860, 10299190,
-+ 10000000, 9875990, 9763770,
-+ 9567070, 9397709, 9252669,
-+ 9124029, 9008929
-+ }
-+ },
-+ /* 16 tap downscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000,
-+ 0, -10000000, -20000000,
-+ -40000000, -60209999, -80000000,
-+ -100000000, -120410003
-+ },
-+ {
-+ 10612260, 10612260, 10612260,
-+ 10000000, 2308720, 1999289,
-+ 1495770, 1009820, 315460,
-+ 99999, 99999
-+ },
-+ {
-+ 9394969, 9394969, 9394969,
-+ 10000000, 3462660, 3162190,
-+ 2780120, 2508420, 2295179,
-+ 2109449, 1943989
-+ },
-+ {
-+ 10609409, 10609409, 10609409,
-+ 10000000, 4749999, 4447000,
-+ 4039109, 3746300, 3522360,
-+ 3336620, 3177059
-+ },
-+ {
-+ 9435039, 9435039, 9435039,
-+ 10000000, 5978109, 5675160,
-+ 5282300, 5000000, 4782429,
-+ 4598149, 4438050
-+ },
-+ {
-+ 10592620, 10592620, 10592620,
-+ 10000000, 7244589, 6940630,
-+ 6537730, 6250000, 6027920,
-+ 5842260, 5680159
-+ },
-+ {
-+ 14282959, 12678509, 11963449,
-+ 10000000, 8484349, 8181620,
-+ 7785459, 7500000, 7281309,
-+ 7095699, 6932809
-+ },
-+ {
-+ 15000000, 11434919, 10673819,
-+ 10000000, 9708179, 9456859,
-+ 9060000, 8760929, 8529940,
-+ 8338279, 8172209
-+ },
-+ {
-+ 11690390, 10668220, 10277210,
-+ 10000000, 9884750, 9780330,
-+ 9597110, 9439319, 9304260,
-+ 9183580, 9075019
-+ }
-+ }
-+};
-+
-+static const int32_t upscaling_db_table[][UP_DB_SCALES+1][UP_DB_POINTS] = {
-+ /* 3 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 14302920, 14302920, 11709250,
-+ 10000000,
-+ 8754609, 7692559, 6738259
-+ }
-+ },
-+ /* 4 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 14308999, 12448530, 11007410,
-+ 10000000, 9165279, 8435800,
-+ 7785279
-+ }
-+ },
-+ /* 5 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 14627330, 12046170, 10862360,
-+ 10000000,
-+ 9312710, 8737679, 8242470
-+ }
-+ },
-+ /* 6 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 13815449, 11911309, 10801299,
-+ 10000000,
-+ 9380580, 8878319, 8452050
-+ }
-+ },
-+ /* 7 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 13752900, 11554559, 10637769,
-+ 10000000,
-+ 9499999, 9079759, 8718389
-+ }
-+ },
-+ /* 8 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 13861900, 11311980, 10543940,
-+ 10000000,
-+ 9565100, 9198870, 8881340
-+ }
-+ },
-+ /* 9 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 12981410, 11185950, 10491620,
-+ 10000000,
-+ 9611030, 9286710, 9007279
-+ }
-+ },
-+ /* 10 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 12507469, 11102950, 10457479,
-+ 10000000,
-+ 9641249, 9344969, 9090980
-+ }
-+ },
-+ /* 11 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 12415319, 10980290, 10405089,
-+ 10000000,
-+ 9680110, 9413710, 9184579
-+ }
-+ },
-+ /* 12 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 12298769, 10886880, 10367530,
-+ 10000000,
-+ 9708030, 9464049, 9252949
-+ }
-+ },
-+ /* 13 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 12039999, 10825289, 10341939,
-+ 10000000,
-+ 9729740, 9505100, 9310669
-+ }
-+ },
-+ /* 14 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 11838380, 10778709, 10322740,
-+ 10000000,
-+ 9746059, 9535790, 9354810
-+ }
-+ },
-+ /* 15 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 11750520, 10722860, 10299190,
-+ 10000000,
-+ 9763770, 9567070, 9397709
-+ }
-+ },
-+ /* 16 tap upscaling */
-+ {
-+ {
-+ 60209999, 40000000, 20000000, 0,
-+ -20000000, -40000000, -60209999
-+ },
-+ {
-+ 11690390, 10668220, 10277210,
-+ 10000000,
-+ 9780330, 9597110, 9439319
-+ }
-+ }
-+};
-+
-+static bool allocate_3d_storage(
-+ struct dc_context *ctx,
-+ struct fixed31_32 ****ptr,
-+ int32_t numberof_tables,
-+ int32_t numberof_rows,
-+ int32_t numberof_columns)
-+{
-+ int32_t indexof_table = 0;
-+ int32_t indexof_row = 0;
-+
-+ struct fixed31_32 ***tables = dc_service_alloc(
-+ ctx,
-+ numberof_tables * sizeof(struct fixed31_32 **));
-+
-+ if (!tables) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ while (indexof_table != numberof_tables) {
-+ struct fixed31_32 **rows = dc_service_alloc(
-+ ctx,
-+ numberof_rows * sizeof(struct fixed31_32 *));
-+
-+ if (!rows) {
-+ BREAK_TO_DEBUGGER();
-+ --indexof_table;
-+ goto failure;
-+ }
-+
-+ tables[indexof_table] = rows;
-+
-+ while (indexof_row != numberof_rows) {
-+ struct fixed31_32 *columns = dc_service_alloc(
-+ ctx,
-+ numberof_columns * sizeof(struct fixed31_32));
-+
-+ if (!columns) {
-+ BREAK_TO_DEBUGGER();
-+ --indexof_row;
-+ goto failure;
-+ }
-+
-+ rows[indexof_row] = columns;
-+
-+ ++indexof_row;
-+ }
-+
-+ indexof_row = 0;
-+
-+ ++indexof_table;
-+ }
-+
-+ *ptr = tables;
-+
-+ return true;
-+
-+failure:
-+
-+ while (indexof_table >= 0) {
-+ while (indexof_row >= 0) {
-+ dc_service_free(ctx, tables[indexof_table][indexof_row]);
-+
-+ --indexof_row;
-+ }
-+
-+ indexof_row = numberof_rows - 1;
-+
-+ dc_service_free(ctx, tables[indexof_table]);
-+
-+ --indexof_table;
-+ }
-+
-+ dc_service_free(ctx, tables);
-+
-+ return false;
-+}
-+
-+static void destroy_3d_storage(
-+ struct dc_context *ctx,
-+ struct fixed31_32 ****ptr,
-+ uint32_t numberof_tables,
-+ uint32_t numberof_rows)
-+{
-+ struct fixed31_32 ***tables = *ptr;
-+
-+ uint32_t indexof_table = 0;
-+
-+ if (!tables)
-+ return;
-+
-+ while (indexof_table != numberof_tables) {
-+ uint32_t indexof_row = 0;
-+
-+ while (indexof_row != numberof_rows) {
-+ dc_service_free(
-+ ctx, tables[indexof_table][indexof_row]);
-+
-+ ++indexof_row;
-+ };
-+
-+ dc_service_free(ctx, tables[indexof_table]);
-+
-+ ++indexof_table;
-+ };
-+
-+ dc_service_free(ctx, tables);
-+
-+ *ptr = NULL;
-+}
-+
-+static bool create_downscaling_table(
-+ struct scaler_filter *filter)
-+{
-+ const int32_t numberof_tables =
-+ ARRAY_SIZE(downscaling_db_table);
-+ const int32_t numberof_rows =
-+ ARRAY_SIZE(downscaling_db_table[0]);
-+ const int32_t numberof_columns =
-+ ARRAY_SIZE(downscaling_db_table[0][0]);
-+
-+ int32_t indexof_table = 0;
-+
-+ if (!allocate_3d_storage(filter->ctx, &filter->downscaling_table,
-+ numberof_tables, numberof_rows, numberof_columns)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ while (indexof_table != numberof_tables) {
-+ struct fixed31_32 **table =
-+ filter->downscaling_table[indexof_table];
-+
-+ int32_t indexof_row = 0;
-+
-+ while (indexof_row != numberof_rows) {
-+ struct fixed31_32 *row = table[indexof_row];
-+
-+ int32_t indexof_column = 0;
-+
-+ while (indexof_column != numberof_columns) {
-+ row[indexof_column] =
-+dal_fixed31_32_from_fraction(
-+ downscaling_db_table[indexof_table][indexof_row][indexof_column],
-+ CONST_DIVIDER);
-+
-+ ++indexof_column;
-+ }
-+
-+ ++indexof_row;
-+ }
-+
-+ ++indexof_table;
-+ }
-+
-+ return true;
-+}
-+
-+static inline void destroy_downscaling_table(
-+ struct scaler_filter *filter)
-+{
-+ destroy_3d_storage(
-+ filter->ctx,
-+ &filter->downscaling_table,
-+ ARRAY_SIZE(downscaling_db_table),
-+ ARRAY_SIZE(downscaling_db_table[0]));
-+}
-+
-+static bool create_upscaling_table(
-+ struct scaler_filter *filter)
-+{
-+ const int32_t numberof_tables =
-+ ARRAY_SIZE(upscaling_db_table);
-+ const int32_t numberof_rows =
-+ ARRAY_SIZE(upscaling_db_table[0]);
-+ const int32_t numberof_columns =
-+ ARRAY_SIZE(upscaling_db_table[0][0]);
-+
-+ int32_t indexof_table = 0;
-+
-+ if (!allocate_3d_storage(filter->ctx, &filter->upscaling_table,
-+ numberof_tables, numberof_rows, numberof_columns)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ while (indexof_table != numberof_tables) {
-+ struct fixed31_32 **table =
-+ filter->upscaling_table[indexof_table];
-+
-+ int32_t indexof_row = 0;
-+
-+ while (indexof_row != numberof_rows) {
-+ struct fixed31_32 *row = table[indexof_row];
-+
-+ int32_t indexof_column = 0;
-+
-+ while (indexof_column != numberof_columns) {
-+ row[indexof_column] =
-+dal_fixed31_32_from_fraction(
-+ upscaling_db_table[indexof_table][indexof_row][indexof_column],
-+ CONST_DIVIDER);
-+
-+ ++indexof_column;
-+ }
-+
-+ ++indexof_row;
-+ }
-+
-+ ++indexof_table;
-+ }
-+
-+ return true;
-+}
-+
-+static inline void destroy_upscaling_table(
-+ struct scaler_filter *filter)
-+{
-+ destroy_3d_storage(
-+ filter->ctx,
-+ &filter->upscaling_table,
-+ ARRAY_SIZE(upscaling_db_table),
-+ ARRAY_SIZE(upscaling_db_table[0]));
-+}
-+
-+static bool same_filter_required(
-+ struct scaler_filter *filter,
-+ const struct scaler_filter_params *params,
-+ uint32_t src_size,
-+ uint32_t dst_size)
-+{
-+ if (!filter->src_size)
-+ return false;
-+ if (!filter->dst_size)
-+ return false;
-+ if (filter->src_size != src_size)
-+ return false;
-+ if (filter->dst_size != dst_size)
-+ return false;
-+ if (filter->params.taps != params->taps)
-+ return false;
-+ if (filter->params.phases != params->phases)
-+ return false;
-+ if (filter->params.sharpness != params->sharpness)
-+ return false;
-+
-+ return true;
-+}
-+
-+/*
-+ * @brief
-+ * (scale_max - scale_min)
-+ * result = scale_min + (value - value_min) * -----------------------
-+ * (value_max - value_min)
-+ */
-+
-+static struct fixed31_32 interpolate(
-+ struct fixed31_32 value,
-+ struct fixed31_32 value_min,
-+ struct fixed31_32 value_max,
-+ struct fixed31_32 scale_min,
-+ struct fixed31_32 scale_max)
-+{
-+ return dal_fixed31_32_add(
-+ scale_min,
-+ dal_fixed31_32_div(
-+ dal_fixed31_32_mul(
-+ dal_fixed31_32_sub(
-+ value,
-+ value_min),
-+ dal_fixed31_32_sub(
-+ scale_max,
-+ scale_min)),
-+ dal_fixed31_32_sub(
-+ value_max,
-+ value_min)));
-+}
-+
-+static bool map_sharpness(
-+ struct scaler_filter *filter,
-+ const struct scaler_filter_params *params,
-+ uint32_t src_size,
-+ uint32_t dst_size,
-+ struct fixed31_32 *attenuation,
-+ struct fixed31_32 *decibels_at_nyquist)
-+{
-+ struct fixed31_32 ratio = dal_fixed31_32_from_fraction(
-+ dst_size,
-+ src_size);
-+
-+ const struct fixed31_32 sharp_flat =
-+ dal_fixed31_32_from_fraction(MIN_SHARPNESS + MAX_SHARPNESS, 2);
-+
-+ struct fixed31_32 sharp_max =
-+ dal_fixed31_32_from_int(MAX_SHARPNESS);
-+ struct fixed31_32 sharp_min =
-+ dal_fixed31_32_from_int(MIN_SHARPNESS);
-+
-+ uint32_t index = params->taps - 3;
-+
-+ struct fixed31_32 ratio_low;
-+ struct fixed31_32 ratio_up;
-+
-+ struct fixed31_32 db_min;
-+ struct fixed31_32 db_flat;
-+ struct fixed31_32 db_max;
-+ struct fixed31_32 db_value;
-+
-+ uint32_t i0;
-+ uint32_t i1;
-+ uint32_t row0;
-+ uint32_t row1;
-+
-+ int32_t sharp = params->sharpness;
-+
-+ if (sharp < MIN_SHARPNESS)
-+ sharp = MIN_SHARPNESS;
-+ else if (sharp > MAX_SHARPNESS)
-+ sharp = MAX_SHARPNESS;
-+
-+ if (params->flags.bits.HORIZONTAL) {
-+ if (dal_fixed31_32_lt(ratio, max_hor_downscale())) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ } else if (dal_fixed31_32_lt(
-+ max_hor_upscale(), ratio)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+ } else {
-+ if (dal_fixed31_32_lt(ratio, max_ver_downscale())) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ } else if (dal_fixed31_32_lt(
-+ max_ver_upscale(), ratio)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+ }
-+
-+ if (dst_size >= src_size) {
-+ if (sharp < 0) {
-+ db_max = up_db_flat();
-+ db_min = up_db_fuzzy();
-+
-+ sharp_max = sharp_flat;
-+ } else {
-+ db_max = up_db_sharp();
-+ db_min = up_db_flat();
-+
-+ sharp_min = sharp_flat;
-+ }
-+
-+ db_value = interpolate(
-+ dal_fixed31_32_from_int(sharp),
-+ sharp_min, sharp_max,
-+ db_min, db_max);
-+
-+ i0 = 0;
-+
-+ while (dal_fixed31_32_lt(
-+ db_value, filter->upscaling_table[index][0][i0]) &&
-+ (i0 < UP_DB_POINTS - 1))
-+ ++i0;
-+
-+ i1 = i0 + 1;
-+
-+ if (i0 == UP_DB_POINTS - 1)
-+ i1 = i0--;
-+
-+ sharp_max = filter->upscaling_table[index][1][i0];
-+ sharp_min = filter->upscaling_table[index][1][i1];
-+
-+ db_max = filter->upscaling_table[index][0][i0];
-+ db_min = filter->upscaling_table[index][0][i1];
-+
-+ *attenuation = interpolate(
-+ db_value,
-+ db_max, db_min,
-+ sharp_max, sharp_min);
-+
-+ *decibels_at_nyquist = db_value;
-+
-+ return true;
-+ } else if ((5 * dst_size) < (src_size << 2)) {
-+ if (sharp < 0) {
-+ db_max = down_db_flat();
-+ db_min = down_db_fuzzy();
-+
-+ sharp_max = sharp_flat;
-+ } else {
-+ db_max = down_db_sharp();
-+ db_min = down_db_flat();
-+
-+ sharp_min = sharp_flat;
-+ }
-+
-+ db_value = interpolate(
-+ dal_fixed31_32_from_int(sharp),
-+ sharp_min, sharp_max,
-+ db_min, db_max);
-+ } else {
-+ struct fixed31_32 db_value_min =
-+ filter->downscaling_table[index][0][0];
-+
-+ struct fixed31_32 db_value_max =
-+ filter->downscaling_table[index][0][DOWN_DB_POINTS - 1];
-+
-+ db_min = interpolate(
-+ ratio,
-+ threshold_ratio_low(), threshold_ratio_up(),
-+ down_db_fuzzy(), up_db_fuzzy());
-+
-+ db_flat = interpolate(
-+ ratio,
-+ threshold_ratio_low(), threshold_ratio_up(),
-+ down_db_flat(), up_db_flat());
-+
-+ db_max = interpolate(
-+ ratio,
-+ threshold_ratio_low(), threshold_ratio_up(),
-+ down_db_sharp(), up_db_sharp());
-+
-+ if (sharp < 0) {
-+ db_max = db_flat;
-+
-+ db_value = interpolate(
-+ dal_fixed31_32_from_int(sharp),
-+ sharp_min, dal_fixed31_32_zero,
-+ db_min, db_max);
-+ } else {
-+ db_min = db_flat;
-+
-+ db_value = interpolate(
-+ dal_fixed31_32_from_int(sharp),
-+ dal_fixed31_32_zero, sharp_max,
-+ db_min, db_max);
-+ }
-+
-+ if (dal_fixed31_32_lt(db_value_min, db_value))
-+ db_value = db_value_min;
-+ else if (dal_fixed31_32_lt(db_value, db_value_max))
-+ db_value = db_value_max;
-+ }
-+
-+ i1 = 0;
-+
-+ while (dal_fixed31_32_lt(db_value,
-+ filter->downscaling_table[index][0][i1]) &&
-+ (i1 < DOWN_DB_POINTS - 1))
-+ ++i1;
-+
-+ if (i1 == 0)
-+ i0 = i1++;
-+ else
-+ i0 = i1 - 1;
-+
-+ row0 = dal_fixed31_32_round(
-+ dal_fixed31_32_mul_int(ratio, DOWN_DB_SCALES));
-+
-+ if (dal_fixed31_32_lt(
-+ dal_fixed31_32_from_fraction(row0, DOWN_DB_SCALES), ratio)) {
-+ row1 = row0 + 1;
-+
-+ if (row1 > DOWN_DB_SCALES) {
-+ row1 = DOWN_DB_SCALES;
-+ row0 = row1 - 1;
-+ }
-+ } else {
-+ row1 = row0--;
-+
-+ if (row0 < 1) {
-+ row0 = 1;
-+ row1 = 2;
-+ }
-+ }
-+
-+ ratio_low = dal_fixed31_32_from_fraction(row0, DOWN_DB_SCALES);
-+ ratio_up = dal_fixed31_32_from_fraction(row1, DOWN_DB_SCALES);
-+
-+ sharp_max = interpolate(
-+ ratio,
-+ ratio_low, ratio_up,
-+ filter->downscaling_table[index][row0][i0],
-+ filter->downscaling_table[index][row1][i0]);
-+
-+ sharp_min = interpolate(
-+ ratio,
-+ ratio_low, ratio_up,
-+ filter->downscaling_table[index][row0][i1],
-+ filter->downscaling_table[index][row1][i1]);
-+
-+ db_max = filter->downscaling_table[index][0][i0];
-+ db_min = filter->downscaling_table[index][0][i1];
-+
-+ *attenuation = interpolate(
-+ db_value,
-+ db_max, db_min,
-+ sharp_max, sharp_min);
-+
-+ *decibels_at_nyquist = db_value;
-+
-+ return true;
-+}
-+
-+static inline struct fixed31_32 lanczos(
-+ struct fixed31_32 x,
-+ struct fixed31_32 a2)
-+{
-+ return dal_fixed31_32_mul(
-+ dal_fixed31_32_sinc(x),
-+ dal_fixed31_32_sinc(
-+ dal_fixed31_32_mul(x, a2)));
-+}
-+
-+static bool generate_filter(
-+ struct scaler_filter *filter,
-+ const struct scaler_filter_params *params,
-+ struct fixed31_32 attenuation,
-+ struct fixed31_32 *ringing)
-+{
-+ uint32_t n = params->phases * params->taps;
-+
-+ uint32_t coefficients_quantity = n;
-+ uint32_t coefficients_sum_quantity = params->phases;
-+
-+ uint32_t i;
-+ uint32_t i_limit;
-+ uint32_t j;
-+ uint32_t m;
-+
-+ struct fixed31_32 attenby2;
-+
-+ struct fixed31_32 a_max = dal_fixed31_32_zero;
-+ struct fixed31_32 a_min = dal_fixed31_32_zero;
-+
-+ if (filter->coefficients_quantity < coefficients_quantity) {
-+ if (filter->coefficients) {
-+ dc_service_free(filter->ctx, filter->coefficients);
-+
-+ filter->coefficients = NULL;
-+ filter->coefficients_quantity = 0;
-+ }
-+
-+ filter->coefficients = dc_service_alloc(
-+ filter->ctx,
-+ coefficients_quantity * sizeof(struct fixed31_32));
-+
-+ if (!filter->coefficients) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ filter->coefficients_quantity = coefficients_quantity;
-+ }
-+
-+ i = 0;
-+
-+ while (i != filter->coefficients_quantity) {
-+ filter->coefficients[i] = dal_fixed31_32_zero;
-+
-+ ++i;
-+ }
-+
-+ if (filter->coefficients_sum_quantity < coefficients_sum_quantity) {
-+ if (filter->coefficients_sum) {
-+ dc_service_free(filter->ctx, filter->coefficients_sum);
-+
-+ filter->coefficients_sum = NULL;
-+ filter->coefficients_sum_quantity = 0;
-+ }
-+
-+ filter->coefficients_sum = dc_service_alloc(
-+ filter->ctx,
-+ coefficients_sum_quantity * sizeof(struct fixed31_32));
-+
-+ if (!filter->coefficients_sum) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ filter->coefficients_sum_quantity = coefficients_sum_quantity;
-+ }
-+
-+ i = 0;
-+
-+ while (i != filter->coefficients_sum_quantity) {
-+ filter->coefficients_sum[i] = dal_fixed31_32_zero;
-+
-+ ++i;
-+ }
-+
-+ m = 0;
-+
-+ attenby2 = dal_fixed31_32_div_int(
-+ dal_fixed31_32_mul_int(attenuation, params->taps), 2);
-+
-+ i = 1;
-+
-+ while (i <= params->taps) {
-+ j = 0;
-+
-+ while (j != params->phases) {
-+ struct fixed31_32 x = dal_fixed31_32_mul(
-+ dal_fixed31_32_pi,
-+ dal_fixed31_32_from_fraction(
-+ (int64_t)(m << 1) - n, n));
-+
-+ uint32_t index =
-+ (params->taps - i) * params->phases + j;
-+
-+ filter->coefficients[index] = lanczos(x, attenby2);
-+
-+ ++m;
-+
-+ ++j;
-+ }
-+
-+ ++i;
-+ }
-+
-+ i = 0;
-+
-+ while (i != params->phases) {
-+ filter->coefficients_sum[i] = dal_fixed31_32_zero;
-+
-+ m = i;
-+
-+ j = 0;
-+
-+ while (j != params->taps) {
-+ filter->coefficients_sum[i] =
-+ dal_fixed31_32_add(
-+ filter->coefficients_sum[i],
-+ filter->coefficients[m]);
-+
-+ m += params->phases;
-+
-+ ++j;
-+ }
-+
-+ ++i;
-+ }
-+
-+ i = 0;
-+
-+ while (i != params->phases) {
-+ m = i;
-+
-+ j = 0;
-+
-+ while (j != params->taps) {
-+ filter->coefficients[m] =
-+ dal_fixed31_32_div(
-+ filter->coefficients[m],
-+ filter->coefficients_sum[i]);
-+
-+ m += params->phases;
-+
-+ ++j;
-+ }
-+
-+ ++i;
-+ }
-+
-+ i = 0;
-+ i_limit = (params->phases >> 1) + 1;
-+
-+ while (i != i_limit) {
-+ m = i;
-+
-+ j = 0;
-+
-+ while (j != params->taps) {
-+ struct fixed31_32 tmp = filter->coefficients[m];
-+
-+ filter->filter[i * params->taps + j] = tmp;
-+
-+ if (dal_fixed31_32_lt(
-+ tmp, dal_fixed31_32_zero) &&
-+ dal_fixed31_32_lt(tmp, a_min))
-+ a_min = tmp;
-+ else if (dal_fixed31_32_lt(
-+ dal_fixed31_32_zero, tmp) &&
-+ dal_fixed31_32_lt(a_max, tmp))
-+ a_max = tmp;
-+
-+ m += params->phases;
-+
-+ ++j;
-+ }
-+
-+ ++i;
-+ }
-+
-+ if (dal_fixed31_32_eq(a_min, dal_fixed31_32_zero))
-+ *ringing = dal_fixed31_32_from_int(100);
-+ else
-+ *ringing = dal_fixed31_32_min(
-+ dal_fixed31_32_abs(
-+ dal_fixed31_32_div(a_max, a_min)),
-+ dal_fixed31_32_from_int(100));
-+
-+ return true;
-+}
-+
-+static bool construct_scaler_filter(
-+ struct dc_context *ctx,
-+ struct scaler_filter *filter)
-+{
-+ filter->src_size = 0;
-+ filter->dst_size = 0;
-+ filter->filter = NULL;
-+ filter->integer_filter = NULL;
-+ filter->filter_size_allocated = 0;
-+ filter->filter_size_effective = 0;
-+ filter->coefficients = NULL;
-+ filter->coefficients_quantity = 0;
-+ filter->coefficients_sum = NULL;
-+ filter->coefficients_sum_quantity = 0;
-+ filter->downscaling_table = NULL;
-+ filter->upscaling_table = NULL;
-+ filter->ctx = ctx;
-+
-+ if (!create_downscaling_table(filter)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!create_upscaling_table(filter)) {
-+ BREAK_TO_DEBUGGER();
-+ destroy_downscaling_table(filter);
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+static void destruct_scaler_filter(
-+ struct scaler_filter *filter)
-+{
-+ if (filter->coefficients_sum)
-+ dc_service_free(filter->ctx, filter->coefficients_sum);
-+
-+ if (filter->coefficients)
-+ dc_service_free(filter->ctx, filter->coefficients);
-+
-+ if (filter->integer_filter)
-+ dc_service_free(filter->ctx, filter->integer_filter);
-+
-+ if (filter->filter)
-+ dc_service_free(filter->ctx, filter->filter);
-+
-+ destroy_upscaling_table(filter);
-+
-+ destroy_downscaling_table(filter);
-+}
-+
-+struct scaler_filter *dal_scaler_filter_create(struct dc_context *ctx)
-+{
-+ struct scaler_filter *filter =
-+ dc_service_alloc(ctx, sizeof(struct scaler_filter));
-+
-+ if (!filter) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ if (construct_scaler_filter(ctx, filter))
-+ return filter;
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ dc_service_free(ctx, filter);
-+
-+ return NULL;
-+}
-+
-+bool dal_scaler_filter_generate(
-+ struct scaler_filter *filter,
-+ const struct scaler_filter_params *params,
-+ uint32_t src_size,
-+ uint32_t dst_size)
-+{
-+ uint32_t filter_size_required;
-+
-+ struct fixed31_32 attenuation;
-+ struct fixed31_32 decibels_at_nyquist;
-+ struct fixed31_32 ringing;
-+
-+ if (!params) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if ((params->taps < 3) || (params->taps > 16)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!src_size || !dst_size) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (same_filter_required(filter, params, src_size, dst_size))
-+ return true;
-+
-+ filter_size_required =
-+ params->taps * ((params->phases >> 1) + 1);
-+
-+ if (filter_size_required > filter->filter_size_allocated) {
-+ if (filter->filter) {
-+ dc_service_free(filter->ctx, filter->filter);
-+
-+ filter->filter = 0;
-+ filter->filter_size_allocated = 0;
-+ }
-+
-+ filter->filter = dc_service_alloc(
-+ filter->ctx,
-+ filter_size_required * sizeof(struct fixed31_32));
-+
-+ if (!filter->filter) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (filter->integer_filter) {
-+ dc_service_free(filter->ctx, filter->integer_filter);
-+
-+ filter->integer_filter = 0;
-+ }
-+
-+ filter->integer_filter = dc_service_alloc(
-+ filter->ctx,
-+ filter_size_required * sizeof(uint32_t));
-+
-+ if (!filter->integer_filter) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ filter->filter_size_allocated = filter_size_required;
-+ }
-+
-+ filter->filter_size_effective = filter_size_required;
-+
-+ if (!map_sharpness(filter, params, src_size, dst_size,
-+ &attenuation, &decibels_at_nyquist)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!generate_filter(filter, params, attenuation, &ringing)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ filter->params = *params;
-+ filter->src_size = src_size;
-+ filter->dst_size = dst_size;
-+
-+ return true;
-+}
-+
-+const struct fixed31_32 *dal_scaler_filter_get(
-+ const struct scaler_filter *filter,
-+ uint32_t **data,
-+ uint32_t *number)
-+{
-+ if (!number) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ if (!data) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ *number = filter->filter_size_effective;
-+ *data = filter->integer_filter;
-+
-+ return filter->filter;
-+}
-+
-+void dal_scaler_filter_destroy(
-+ struct scaler_filter **filter)
-+{
-+ if (!filter || !*filter) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ destruct_scaler_filter(*filter);
-+
-+ dc_service_free((*filter)->ctx, *filter);
-+
-+ *filter = NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/calcs/scaler_filter.h b/drivers/gpu/drm/amd/dal/dc/calcs/scaler_filter.h
-new file mode 100644
-index 0000000..668691d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/calcs/scaler_filter.h
-@@ -0,0 +1,74 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_SCALER_FILTER_H__
-+#define __DAL_SCALER_FILTER_H__
-+
-+struct scaler_filter_params {
-+ uint32_t taps; /* 3...16 */
-+ uint32_t phases;
-+ int32_t sharpness; /* -50...50 */
-+ union {
-+ struct {
-+ uint32_t HORIZONTAL:1;
-+ uint32_t RESERVED:31;
-+ } bits;
-+ uint32_t value;
-+ } flags;
-+};
-+
-+struct q31_32;
-+
-+struct scaler_filter {
-+ struct scaler_filter_params params;
-+ uint32_t src_size;
-+ uint32_t dst_size;
-+ struct fixed31_32 *filter;
-+ uint32_t *integer_filter;
-+ uint32_t filter_size_allocated;
-+ uint32_t filter_size_effective;
-+ struct fixed31_32 *coefficients;
-+ uint32_t coefficients_quantity;
-+ struct fixed31_32 *coefficients_sum;
-+ uint32_t coefficients_sum_quantity;
-+ struct fixed31_32 ***downscaling_table;
-+ struct fixed31_32 ***upscaling_table;
-+ struct dc_context *ctx;
-+};
-+
-+struct scaler_filter *dal_scaler_filter_create(struct dc_context *ctx);
-+void dal_scaler_filter_destroy(struct scaler_filter **ptr);
-+
-+bool dal_scaler_filter_generate(
-+ struct scaler_filter *filter,
-+ const struct scaler_filter_params *params,
-+ uint32_t src_size,
-+ uint32_t dst_size);
-+
-+const struct fixed31_32 *dal_scaler_filter_get(
-+ const struct scaler_filter *filter,
-+ uint32_t **data,
-+ uint32_t *number);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/connector/Makefile b/drivers/gpu/drm/amd/dal/dc/connector/Makefile
-new file mode 100644
-index 0000000..ebd4115
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/connector/Makefile
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the 'connector' sub-component of DAL.
-+# It provides the control and status of HW connectors blocks.
-+
-+
-+CONNECTOR = connector_base.o connector_signals.o
-+
-+AMD_DAL_CONNECTOR = $(addprefix $(AMDDALPATH)/dc/connector/,$(CONNECTOR))
-+
-+AMD_DAL_FILES += $(AMD_DAL_CONNECTOR)
-diff --git a/drivers/gpu/drm/amd/dal/dc/connector/connector.h b/drivers/gpu/drm/amd/dal/dc/connector/connector.h
-new file mode 100644
-index 0000000..7d6057b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/connector/connector.h
-@@ -0,0 +1,39 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_CONNECTOR_H__
-+#define __DAL_CONNECTOR_H__
-+
-+#include "include/connector_interface.h"
-+
-+extern const uint32_t number_of_default_signals;
-+extern const uint32_t number_of_signals;
-+
-+/* Indexed by enum connector_id */
-+extern const struct connector_signals default_signals[];
-+/* Indexed by enum connector_id */
-+extern const struct connector_signals supported_signals[];
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/connector/connector_base.c b/drivers/gpu/drm/amd/dal/dc/connector/connector_base.c
-new file mode 100644
-index 0000000..34005fd
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/connector/connector_base.c
-@@ -0,0 +1,421 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "connector.h"
-+#include "include/irq_interface.h"
-+#include "include/ddc_interface.h"
-+#include "include/connector_interface.h"
-+
-+struct connector {
-+ struct graphics_object_id id;
-+ uint32_t input_signals;
-+ uint32_t output_signals;
-+ struct adapter_service *as;
-+ struct connector_feature_support features;
-+ struct connector_signals default_signals;
-+ struct dc_context *ctx;
-+};
-+
-+static bool connector_construct(
-+ struct connector *connector,
-+ struct dc_context *ctx,
-+ struct adapter_service *as,
-+ struct graphics_object_id go_id)
-+{
-+ bool hw_ddc_polling = false;
-+ struct ddc *ddc;
-+ struct irq *hpd;
-+ enum connector_id connector_id;
-+ uint32_t signals_vector = 0;
-+ uint32_t signals_num = 0;
-+ uint32_t i;
-+
-+ if (!as) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ connector->as = as;
-+ connector->id = go_id;
-+ connector->features.ddc_line = CHANNEL_ID_UNKNOWN;
-+ connector->features.hpd_line = HPD_SOURCEID_UNKNOWN;
-+ connector->ctx = ctx;
-+
-+ ddc = dal_adapter_service_obtain_ddc(as, connector->id);
-+ hpd = dal_adapter_service_obtain_hpd_irq(as, connector->id);
-+
-+ connector_id = dal_graphics_object_id_get_connector_id(go_id);
-+
-+ /* Initialize DDC line */
-+ if (ddc) {
-+ switch (dal_ddc_get_line(ddc)) {
-+ case GPIO_DDC_LINE_DDC1:
-+ connector->features.ddc_line = CHANNEL_ID_DDC1;
-+ break;
-+ case GPIO_DDC_LINE_DDC2:
-+ connector->features.ddc_line = CHANNEL_ID_DDC2;
-+ break;
-+ case GPIO_DDC_LINE_DDC3:
-+ connector->features.ddc_line = CHANNEL_ID_DDC3;
-+ break;
-+ case GPIO_DDC_LINE_DDC4:
-+ connector->features.ddc_line = CHANNEL_ID_DDC4;
-+ break;
-+ case GPIO_DDC_LINE_DDC5:
-+ connector->features.ddc_line = CHANNEL_ID_DDC5;
-+ break;
-+ case GPIO_DDC_LINE_DDC6:
-+ connector->features.ddc_line = CHANNEL_ID_DDC6;
-+ break;
-+ case GPIO_DDC_LINE_DDC_VGA:
-+ connector->features.ddc_line = CHANNEL_ID_DDC_VGA;
-+ break;
-+ case GPIO_DDC_LINE_I2C_PAD:
-+ connector->features.ddc_line = CHANNEL_ID_I2C_PAD;
-+ break;
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ break;
-+ }
-+
-+ /* Initialize HW DDC polling support
-+ * On DCE6.0 only DDC lines support HW polling (I2cPad does not)
-+ */
-+
-+ if (dal_adapter_service_is_feature_supported(
-+ FEATURE_ENABLE_HW_EDID_POLLING)) {
-+ switch (dal_ddc_get_line(ddc)) {
-+ case GPIO_DDC_LINE_DDC1:
-+ case GPIO_DDC_LINE_DDC2:
-+ case GPIO_DDC_LINE_DDC3:
-+ case GPIO_DDC_LINE_DDC4:
-+ case GPIO_DDC_LINE_DDC5:
-+ case GPIO_DDC_LINE_DDC6:
-+ case GPIO_DDC_LINE_DDC_VGA:
-+ hw_ddc_polling = true;
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ dal_adapter_service_release_ddc(as, ddc);
-+ }
-+
-+ /* Initialize HPD line */
-+ if (hpd) {
-+ switch (dal_irq_get_source(hpd)) {
-+ case DC_IRQ_SOURCE_HPD1:
-+ connector->features.hpd_line = HPD_SOURCEID1;
-+ break;
-+ case DC_IRQ_SOURCE_HPD2:
-+ connector->features.hpd_line = HPD_SOURCEID2;
-+ break;
-+ case DC_IRQ_SOURCE_HPD3:
-+ connector->features.hpd_line = HPD_SOURCEID3;
-+ break;
-+ case DC_IRQ_SOURCE_HPD4:
-+ connector->features.hpd_line = HPD_SOURCEID4;
-+ break;
-+ case DC_IRQ_SOURCE_HPD5:
-+ connector->features.hpd_line = HPD_SOURCEID5;
-+ break;
-+ case DC_IRQ_SOURCE_HPD6:
-+ connector->features.hpd_line = HPD_SOURCEID6;
-+ break;
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ break;
-+ }
-+
-+ dal_adapter_service_release_irq(as, hpd);
-+ }
-+
-+ if ((uint32_t)connector_id >= number_of_default_signals &&
-+ (uint32_t)connector_id >= number_of_signals)
-+ return false;
-+
-+ /* Initialize default signals */
-+ connector->default_signals = default_signals[connector_id];
-+
-+ /* Fill supported signals */
-+ signals_num = supported_signals[connector_id].number_of_signals;
-+ for (i = 0; i < signals_num; i++)
-+ signals_vector |= supported_signals[connector_id].signal[i];
-+
-+ /* Connector supports same set for input and output signals */
-+ connector->input_signals = signals_vector;
-+ connector->output_signals = signals_vector;
-+
-+ switch (connector_id) {
-+ case CONNECTOR_ID_VGA:
-+ if (hw_ddc_polling
-+ && connector->features.ddc_line != CHANNEL_ID_UNKNOWN)
-+ connector->features.HW_DDC_POLLING = true;
-+ break;
-+ case CONNECTOR_ID_SINGLE_LINK_DVII:
-+ case CONNECTOR_ID_DUAL_LINK_DVII:
-+ if (connector->features.hpd_line != HPD_SOURCEID_UNKNOWN)
-+ connector->features.HPD_FILTERING = true;
-+ if (hw_ddc_polling
-+ && connector->features.ddc_line != CHANNEL_ID_UNKNOWN)
-+ connector->features.HW_DDC_POLLING = true;
-+ break;
-+ case CONNECTOR_ID_SINGLE_LINK_DVID:
-+ case CONNECTOR_ID_DUAL_LINK_DVID:
-+ case CONNECTOR_ID_HDMI_TYPE_A:
-+ case CONNECTOR_ID_LVDS:
-+ case CONNECTOR_ID_DISPLAY_PORT:
-+ case CONNECTOR_ID_EDP:
-+ if (connector->features.hpd_line != HPD_SOURCEID_UNKNOWN)
-+ connector->features.HPD_FILTERING = true;
-+ break;
-+ default:
-+ connector->features.HPD_FILTERING = false;
-+ connector->features.HW_DDC_POLLING = false;
-+ break;
-+ }
-+
-+ return true;
-+}
-+
-+struct connector *dal_connector_create(
-+ struct dc_context *ctx,
-+ struct adapter_service *as,
-+ struct graphics_object_id go_id)
-+{
-+ struct connector *connector = NULL;
-+
-+ connector = dc_service_alloc(ctx, sizeof(struct connector));
-+
-+ if (!connector) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ if (connector_construct(connector, ctx, as, go_id))
-+ return connector;
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ dc_service_free(ctx, connector);
-+
-+ return NULL;
-+}
-+
-+void dal_connector_destroy(struct connector **connector)
-+{
-+ if (!connector || !*connector) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ dc_service_free((*connector)->ctx, *connector);
-+
-+ *connector = NULL;
-+}
-+
-+uint32_t dal_connector_enumerate_output_signals(
-+ const struct connector *connector)
-+{
-+ return connector->output_signals;
-+}
-+
-+uint32_t dal_connector_enumerate_input_signals(
-+ const struct connector *connector)
-+{
-+ return connector->input_signals;
-+}
-+
-+struct connector_signals dal_connector_get_default_signals(
-+ const struct connector *connector)
-+{
-+ return connector->default_signals;
-+}
-+
-+const struct graphics_object_id dal_connector_get_graphics_object_id(
-+ const struct connector *connector)
-+{
-+ return connector->id;
-+}
-+
-+/*
-+ * Function: program_hpd_filter
-+ *
-+ * @brief
-+ * Programs HPD filter on associated HPD line
-+ *
-+ * @param [in] delay_on_connect_in_ms: Connect filter timeout
-+ * @param [in] delay_on_disconnect_in_ms: Disconnect filter timeout
-+ *
-+ * @return
-+ * true on success, false otherwise
-+ */
-+bool dal_connector_program_hpd_filter(
-+ const struct connector *connector,
-+ const uint32_t delay_on_connect_in_ms,
-+ const uint32_t delay_on_disconnect_in_ms)
-+{
-+ bool result = false;
-+
-+ struct irq *hpd;
-+
-+ /* Verify feature is supported */
-+
-+ if (!connector->features.HPD_FILTERING)
-+ return result;
-+
-+ /* Obtain HPD handle */
-+
-+ hpd = dal_adapter_service_obtain_hpd_irq(
-+ connector->as, connector->id);
-+
-+ if (!hpd)
-+ return result;
-+
-+ /* Setup HPD filtering */
-+
-+ if (GPIO_RESULT_OK == dal_irq_open(hpd)) {
-+ struct gpio_hpd_config config;
-+
-+ config.delay_on_connect = delay_on_connect_in_ms;
-+ config.delay_on_disconnect = delay_on_disconnect_in_ms;
-+
-+ dal_irq_setup_hpd_filter(hpd, &config);
-+
-+ dal_irq_close(hpd);
-+
-+ result = true;
-+ } else {
-+ ASSERT_CRITICAL(false);
-+ }
-+
-+ /* Release HPD handle */
-+
-+ dal_adapter_service_release_irq(connector->as, hpd);
-+
-+ return result;
-+}
-+
-+/*
-+ * Function: setup_ddc_polling
-+ *
-+ * @brief
-+ * Enables/Disables HW polling on associated DDC line
-+ *
-+ * @param [in] ddc_config: Specifies polling mode
-+ *
-+ * @return
-+ * true on success, false otherwise
-+ */
-+static bool setup_ddc_polling(
-+ const struct connector *connector,
-+ enum gpio_ddc_config_type ddc_config)
-+{
-+ bool result = false;
-+
-+ struct ddc *ddc;
-+
-+ /* Verify feature is supported */
-+
-+ if (!connector->features.HW_DDC_POLLING)
-+ return result;
-+
-+ /* Obtain DDC handle */
-+
-+ ddc = dal_adapter_service_obtain_ddc(
-+ connector->as, connector->id);
-+
-+ if (!ddc) {
-+ BREAK_TO_DEBUGGER();
-+ return result;
-+ }
-+
-+ /* Setup DDC polling */
-+
-+ if (GPIO_RESULT_OK == dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
-+ GPIO_DDC_CONFIG_TYPE_MODE_I2C)) {
-+ dal_ddc_set_config(ddc, ddc_config);
-+
-+ dal_ddc_close(ddc);
-+
-+ result = true;
-+ } else {
-+ BREAK_TO_DEBUGGER();
-+ }
-+
-+ /* Release DDC handle */
-+
-+ dal_adapter_service_release_ddc(connector->as, ddc);
-+
-+ return result;
-+}
-+
-+/*
-+ * Function: enable_ddc_polling
-+ *
-+ * @brief
-+ * Enables HW polling on associated DDC line
-+ *
-+ * @param [in] is_poll_for_connect: Specifies polling mode
-+ *
-+ * @return
-+ * true on success, false otherwise
-+ */
-+bool dal_connector_enable_ddc_polling(
-+ const struct connector *connector,
-+ const bool is_poll_for_connect)
-+{
-+ enum gpio_ddc_config_type ddc_config = is_poll_for_connect ?
-+ GPIO_DDC_CONFIG_TYPE_POLL_FOR_CONNECT :
-+ GPIO_DDC_CONFIG_TYPE_POLL_FOR_DISCONNECT;
-+
-+ return setup_ddc_polling(connector, ddc_config);
-+}
-+
-+/*
-+ * Function: disable_ddc_polling
-+ *
-+ * @brief
-+ * Disables HW polling on associated DDC line
-+ *
-+ * @return
-+ * true on success, false otherwise
-+ */
-+bool dal_connector_disable_ddc_polling(const struct connector *connector)
-+{
-+ return setup_ddc_polling(connector,
-+ GPIO_DDC_CONFIG_TYPE_DISABLE_POLLING);
-+}
-+
-+void dal_connector_get_features(
-+ const struct connector *con,
-+ struct connector_feature_support *cfs)
-+{
-+ dc_service_memmove(cfs, &con->features,
-+ sizeof(struct connector_feature_support));
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/connector/connector_signals.c b/drivers/gpu/drm/amd/dal/dc/connector/connector_signals.c
-new file mode 100644
-index 0000000..d1a289d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/connector/connector_signals.c
-@@ -0,0 +1,204 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "connector.h"
-+
-+static const enum signal_type signals_none[] = {
-+ SIGNAL_TYPE_NONE
-+};
-+
-+static const enum signal_type signals_single_link_dvii[] = {
-+ SIGNAL_TYPE_DVI_SINGLE_LINK,
-+ SIGNAL_TYPE_RGB
-+};
-+
-+static const enum signal_type signals_dual_link_dvii[] = {
-+ SIGNAL_TYPE_DVI_DUAL_LINK,
-+ SIGNAL_TYPE_DVI_SINGLE_LINK,
-+ SIGNAL_TYPE_RGB
-+};
-+
-+static const enum signal_type signals_single_link_dvid[] = {
-+ SIGNAL_TYPE_DVI_SINGLE_LINK
-+};
-+
-+static const enum signal_type signals_dual_link_dvid[] = {
-+ SIGNAL_TYPE_DVI_DUAL_LINK,
-+ SIGNAL_TYPE_DVI_SINGLE_LINK,
-+};
-+
-+static const enum signal_type signals_vga[] = {
-+ SIGNAL_TYPE_RGB
-+};
-+
-+static const enum signal_type signals_hdmi_type_a[] = {
-+ SIGNAL_TYPE_DVI_SINGLE_LINK,
-+ SIGNAL_TYPE_HDMI_TYPE_A
-+};
-+
-+static const enum signal_type signals_lvds[] = {
-+ SIGNAL_TYPE_LVDS
-+};
-+
-+static const enum signal_type signals_pcie[] = {
-+ SIGNAL_TYPE_DVI_SINGLE_LINK,
-+ SIGNAL_TYPE_HDMI_TYPE_A,
-+ SIGNAL_TYPE_DISPLAY_PORT
-+};
-+
-+static const enum signal_type signals_hardcode_dvi[] = {
-+ SIGNAL_TYPE_NONE
-+};
-+
-+static const enum signal_type signals_displayport[] = {
-+ SIGNAL_TYPE_DVI_SINGLE_LINK,
-+ SIGNAL_TYPE_HDMI_TYPE_A,
-+ SIGNAL_TYPE_DISPLAY_PORT,
-+ SIGNAL_TYPE_DISPLAY_PORT_MST
-+};
-+
-+static const enum signal_type signals_edp[] = {
-+ SIGNAL_TYPE_EDP
-+};
-+
-+static const enum signal_type signals_wireless[] = {
-+ SIGNAL_TYPE_WIRELESS
-+};
-+
-+static const enum signal_type signals_miracast[] = {
-+ SIGNAL_TYPE_WIRELESS
-+};
-+
-+static const enum signal_type default_signals_none[] = {
-+ SIGNAL_TYPE_NONE
-+};
-+
-+static const enum signal_type default_signals_single_link_dvii[] = {
-+ SIGNAL_TYPE_DVI_SINGLE_LINK,
-+ SIGNAL_TYPE_RGB
-+};
-+
-+static const enum signal_type default_signals_dual_link_dvii[] = {
-+ SIGNAL_TYPE_DVI_DUAL_LINK,
-+ SIGNAL_TYPE_RGB
-+};
-+
-+static const enum signal_type default_signals_single_link_dvid[] = {
-+ SIGNAL_TYPE_DVI_SINGLE_LINK
-+};
-+
-+static const enum signal_type default_signals_dual_link_dvid[] = {
-+ SIGNAL_TYPE_DVI_DUAL_LINK,
-+};
-+
-+static const enum signal_type default_signals_vga[] = {
-+ SIGNAL_TYPE_RGB
-+};
-+
-+static const enum signal_type default_signals_hdmi_type_a[] = {
-+ SIGNAL_TYPE_HDMI_TYPE_A
-+};
-+
-+static const enum signal_type default_signals_lvds[] = {
-+ SIGNAL_TYPE_LVDS
-+};
-+
-+static const enum signal_type default_signals_pcie[] = {
-+ SIGNAL_TYPE_DISPLAY_PORT
-+};
-+
-+static const enum signal_type default_signals_hardcode_dvi[] = {
-+ SIGNAL_TYPE_NONE
-+};
-+
-+static const enum signal_type default_signals_displayport[] = {
-+ SIGNAL_TYPE_DISPLAY_PORT
-+};
-+
-+static const enum signal_type default_signals_edp[] = {
-+ SIGNAL_TYPE_EDP
-+};
-+
-+static const enum signal_type default_signals_wireless[] = {
-+ SIGNAL_TYPE_WIRELESS
-+};
-+
-+static const enum signal_type default_signals_miracast[] = {
-+ SIGNAL_TYPE_WIRELESS
-+};
-+
-+/*
-+ * Signal arrays
-+ */
-+
-+#define SIGNALS_ARRAY_ELEM(a) {a, ARRAY_SIZE(a)}
-+
-+/* Indexed by enum connector_id */
-+const struct connector_signals default_signals[] = {
-+ SIGNALS_ARRAY_ELEM(default_signals_none),
-+ SIGNALS_ARRAY_ELEM(default_signals_single_link_dvii),
-+ SIGNALS_ARRAY_ELEM(default_signals_dual_link_dvii),
-+ SIGNALS_ARRAY_ELEM(default_signals_single_link_dvid),
-+ SIGNALS_ARRAY_ELEM(default_signals_dual_link_dvid),
-+ SIGNALS_ARRAY_ELEM(default_signals_vga),
-+ SIGNALS_ARRAY_ELEM(default_signals_hdmi_type_a),
-+ SIGNALS_ARRAY_ELEM(default_signals_none),
-+ SIGNALS_ARRAY_ELEM(default_signals_lvds),
-+ SIGNALS_ARRAY_ELEM(default_signals_pcie),
-+ SIGNALS_ARRAY_ELEM(default_signals_hardcode_dvi),
-+ SIGNALS_ARRAY_ELEM(default_signals_displayport),
-+ SIGNALS_ARRAY_ELEM(default_signals_edp),
-+ /* MXM dummy connector */
-+ SIGNALS_ARRAY_ELEM(default_signals_none),
-+ SIGNALS_ARRAY_ELEM(default_signals_wireless),
-+ SIGNALS_ARRAY_ELEM(default_signals_miracast)
-+};
-+
-+const uint32_t number_of_default_signals = ARRAY_SIZE(default_signals);
-+
-+/* Indexed by enum connector_id */
-+const struct connector_signals supported_signals[] = {
-+ SIGNALS_ARRAY_ELEM(signals_none),
-+ SIGNALS_ARRAY_ELEM(signals_single_link_dvii),
-+ SIGNALS_ARRAY_ELEM(signals_dual_link_dvii),
-+ SIGNALS_ARRAY_ELEM(signals_single_link_dvid),
-+ SIGNALS_ARRAY_ELEM(signals_dual_link_dvid),
-+ SIGNALS_ARRAY_ELEM(signals_vga),
-+ SIGNALS_ARRAY_ELEM(signals_hdmi_type_a),
-+ SIGNALS_ARRAY_ELEM(signals_none),
-+ SIGNALS_ARRAY_ELEM(signals_lvds),
-+ SIGNALS_ARRAY_ELEM(signals_pcie),
-+ SIGNALS_ARRAY_ELEM(signals_hardcode_dvi),
-+ SIGNALS_ARRAY_ELEM(signals_displayport),
-+ SIGNALS_ARRAY_ELEM(signals_edp),
-+ /* MXM dummy connector */
-+ SIGNALS_ARRAY_ELEM(signals_none),
-+ SIGNALS_ARRAY_ELEM(signals_wireless),
-+ SIGNALS_ARRAY_ELEM(signals_miracast)
-+};
-+
-+const uint32_t number_of_signals = ARRAY_SIZE(supported_signals);
-diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc.c b/drivers/gpu/drm/amd/dal/dc/core/dc.c
-new file mode 100644
-index 0000000..e13ce4e
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/core/dc.c
-@@ -0,0 +1,849 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ */
-+
-+#include "dc_services.h"
-+
-+#include "dc.h"
-+
-+#include "core_status.h"
-+#include "core_types.h"
-+#include "hw_sequencer.h"
-+
-+#include "resource.h"
-+
-+#include "adapter_service_interface.h"
-+#include "clock_source_interface.h"
-+
-+#include "include/irq_service_interface.h"
-+#include "bandwidth_calcs.h"
-+#include "include/irq_service_interface.h"
-+
-+#include "link_hwss.h"
-+
-+/*******************************************************************************
-+ * Private structures
-+ ******************************************************************************/
-+
-+struct dc_target_sync_report {
-+ uint32_t h_count;
-+ uint32_t v_count;
-+};
-+
-+struct dc_sync_report {
-+ uint32_t targets_num;
-+ struct dc_target_sync_report trg_reports[MAX_TARGET_NUM];
-+};
-+
-+/*******************************************************************************
-+ * Private functions
-+ ******************************************************************************/
-+static void destroy_links(struct dc *dc)
-+{
-+ uint32_t i;
-+
-+ for (i = 0; i < dc->link_count; i++) {
-+
-+ if (NULL != dc->links[i])
-+ link_destroy(&dc->links[i]);
-+ }
-+}
-+
-+
-+static bool create_links(struct dc *dc, const struct dc_init_data *init_params)
-+{
-+ int i;
-+ int connectors_num;
-+
-+ dc->link_count = 0;
-+
-+ connectors_num = dal_bios_parser_get_connectors_number(
-+ dal_adapter_service_get_bios_parser(
-+ init_params->adapter_srv));
-+
-+ if (0 == connectors_num || connectors_num > ENUM_ID_COUNT) {
-+ dal_error("DC: Invalid number of connectors!\n");
-+ return false;
-+ }
-+
-+ dal_output_to_console("%s: connectors_num:%d\n", __func__,
-+ connectors_num);
-+
-+ dc->links = dc_service_alloc(
-+ init_params->ctx, connectors_num * sizeof(struct core_link *));
-+
-+ if (NULL == dc->links) {
-+ dal_error("DC: failed to allocate 'links' storage!\n");
-+ goto allocate_dc_links_storage_fail;
-+ }
-+
-+ for (i = 0; i < connectors_num; i++) {
-+ struct link_init_data link_init_params = {0};
-+ struct core_link *link;
-+
-+ link_init_params.ctx = init_params->ctx;
-+ link_init_params.adapter_srv = init_params->adapter_srv;
-+ link_init_params.connector_index = i;
-+ link_init_params.link_index = dc->link_count;
-+ link_init_params.dc = dc;
-+ link = link_create(&link_init_params);
-+
-+ if (link) {
-+ dc->links[dc->link_count] = link;
-+ link->dc = dc;
-+ ++dc->link_count;
-+ }
-+ else {
-+ dal_error("DC: failed to create link!\n");
-+ }
-+ }
-+
-+ if (!dc->link_count) {
-+ dal_error("DC: no 'links' were created!\n");
-+ goto allocate_dc_links_storage_fail;
-+ }
-+
-+ return true;
-+
-+allocate_dc_links_storage_fail:
-+ return false;
-+}
-+
-+static void init_hw(struct dc *dc)
-+{
-+ int i;
-+ struct bios_parser *bp;
-+ struct transform *xfm;
-+
-+ bp = dal_adapter_service_get_bios_parser(dc->res_pool.adapter_srv);
-+ for(i = 0; i < dc->res_pool.controller_count; i++) {
-+ xfm = dc->res_pool.transforms[i];
-+
-+ dc->hwss.enable_display_power_gating(
-+ dc->ctx, i, bp,
-+ PIPE_GATING_CONTROL_INIT);
-+ dc->hwss.enable_display_power_gating(
-+ dc->ctx, i, bp,
-+ PIPE_GATING_CONTROL_DISABLE);
-+
-+ dc->hwss.transform_power_up(xfm);
-+ dc->hwss.enable_display_pipe_clock_gating(
-+ dc->ctx,
-+ true);
-+ }
-+
-+ dc->hwss.clock_gating_power_up(dc->ctx, false);
-+ dal_bios_parser_power_up(bp);
-+ /***************************************/
-+
-+ for (i = 0; i < dc->link_count; i++) {
-+ /****************************************/
-+ /* Power up AND update implementation according to the
-+ * required signal (which may be different from the
-+ * default signal on connector). */
-+ struct core_link *link = dc->links[i];
-+ if (dc->hwss.encoder_power_up(link->link_enc) != ENCODER_RESULT_OK) {
-+ dal_error("Failed link encoder power up!\n");
-+ return;
-+ }
-+ }
-+
-+ dal_bios_parser_set_scratch_acc_mode_change(bp);
-+
-+ for(i = 0; i < dc->res_pool.controller_count; i++) {
-+ struct timing_generator *tg = dc->res_pool.timing_generators[i];
-+
-+ dc->hwss.disable_vga(tg);
-+
-+ /* Blank controller using driver code instead of
-+ * command table. */
-+ dc->hwss.disable_memory_requests(tg);
-+ }
-+
-+ for(i = 0; i < dc->res_pool.audio_count; i++) {
-+ struct audio *audio = dc->res_pool.audios[i];
-+
-+ if (dal_audio_power_up(audio) != AUDIO_RESULT_OK)
-+ dal_error("Failed audio power up!\n");
-+ }
-+
-+}
-+
-+static struct adapter_service *create_as(
-+ struct dc_init_data *dc_init_data,
-+ const struct dal_init_data *init)
-+{
-+ struct adapter_service *as = NULL;
-+ struct as_init_data init_data;
-+
-+ dc_service_memset(&init_data, 0, sizeof(init_data));
-+
-+ init_data.ctx = dc_init_data->ctx;
-+
-+ /* BIOS parser init data */
-+ init_data.bp_init_data.ctx = dc_init_data->ctx;
-+ init_data.bp_init_data.bios = init->asic_id.atombios_base_address;
-+
-+ /* HW init data */
-+ init_data.hw_init_data.chip_id = init->asic_id.chip_id;
-+ init_data.hw_init_data.chip_family = init->asic_id.chip_family;
-+ init_data.hw_init_data.pci_revision_id = init->asic_id.pci_revision_id;
-+ init_data.hw_init_data.fake_paths_num = init->asic_id.fake_paths_num;
-+ init_data.hw_init_data.feature_flags = init->asic_id.feature_flags;
-+ init_data.hw_init_data.hw_internal_rev = init->asic_id.hw_internal_rev;
-+ init_data.hw_init_data.runtime_flags = init->asic_id.runtime_flags;
-+ init_data.hw_init_data.vram_width = init->asic_id.vram_width;
-+ init_data.hw_init_data.vram_type = init->asic_id.vram_type;
-+
-+ /* bdf is BUS,DEVICE,FUNCTION*/
-+ init_data.bdf_info = init->bdf_info;
-+
-+ init_data.display_param = &init->display_param;
-+
-+ as = dal_adapter_service_create(&init_data);
-+
-+ return as;
-+}
-+
-+static void bw_calcs_data_update_from_pplib(struct dc *dc)
-+{
-+ struct dal_system_clock_range clk_range = { 0 };
-+
-+ dc_service_get_system_clocks_range(dc->ctx, &clk_range);
-+
-+ /* on CZ Gardenia from PPLib we get:
-+ * clk_range.max_mclk:80000
-+ * clk_range.min_mclk:80000
-+ * clk_range.max_sclk:80000
-+ * clk_range.min_sclk:30000 */
-+
-+ /* The values for calcs are stored in units of MHz, so for example
-+ * 80000 will be stored as 800. */
-+ dc->bw_vbios.high_sclk = frc_to_fixed(clk_range.max_sclk, 100);
-+ dc->bw_vbios.low_sclk = frc_to_fixed(clk_range.min_sclk, 100);
-+
-+ dc->bw_vbios.high_yclk = frc_to_fixed(clk_range.max_mclk, 100);
-+ dc->bw_vbios.low_yclk = frc_to_fixed(clk_range.min_mclk, 100);
-+}
-+
-+static bool construct(struct dc *dc, const struct dal_init_data *init_params)
-+{
-+ struct dal_logger *logger;
-+ /* Tempory code
-+ * TODO: replace dal_init_data with dc_init_data when dal is removed
-+ */
-+ struct dc_init_data dc_init_data = {0};
-+
-+ /* Create dc context */
-+ /* A temp dc context is used only to allocate the memory for actual
-+ * dc context */
-+ struct dc_context ctx = {0};
-+ ctx.cgs_device = init_params->cgs_device;
-+ ctx.dc = dc;
-+
-+ dc_init_data.ctx = dc_service_alloc(&ctx, sizeof(*dc_init_data.ctx));
-+ if (!dc_init_data.ctx) {
-+ dal_error("%s: failed to create ctx\n", __func__);
-+ goto ctx_fail;
-+ }
-+ dc_init_data.ctx->driver_context = init_params->driver;
-+ dc_init_data.ctx->cgs_device = init_params->cgs_device;
-+ dc_init_data.ctx->dc = dc;
-+
-+ /* Create logger */
-+ logger = dal_logger_create(dc_init_data.ctx);
-+
-+ if (!logger) {
-+ /* can *not* call logger. call base driver 'print error' */
-+ dal_error("%s: failed to create Logger!\n", __func__);
-+ goto logger_fail;
-+ }
-+ dc_init_data.ctx->logger = logger;
-+
-+ /* Create adapter service */
-+ dc_init_data.adapter_srv = create_as(&dc_init_data, init_params);
-+
-+ if (!dc_init_data.adapter_srv) {
-+ dal_error("%s: create_as() failed!\n", __func__);
-+ goto as_fail;
-+ }
-+
-+ /* Initialize HW controlled by Adapter Service */
-+ if (false == dal_adapter_service_initialize_hw_data(
-+ dc_init_data.adapter_srv)) {
-+ dal_error("%s: dal_adapter_service_initialize_hw_data()"\
-+ " failed!\n", __func__);
-+ /* Note that AS exist, so have to destroy it.*/
-+ goto as_fail;
-+ }
-+
-+ dc->ctx = dc_init_data.ctx;
-+
-+ /* Create hardware sequencer */
-+ if (!dc_construct_hw_sequencer(dc_init_data.adapter_srv, dc))
-+ goto hwss_fail;
-+
-+
-+ /* TODO: create all the sub-objects of DC. */
-+ if (false == create_links(dc, &dc_init_data))
-+ goto create_links_fail;
-+
-+ if (!dc->hwss.construct_resource_pool(
-+ dc_init_data.adapter_srv,
-+ dc,
-+ &dc->res_pool))
-+ goto construct_resource_fail;
-+
-+
-+ bw_calcs_init(&dc->bw_dceip, &dc->bw_vbios);
-+
-+ bw_calcs_data_update_from_pplib(dc);
-+
-+ return true;
-+
-+ /**** error handling here ****/
-+construct_resource_fail:
-+create_links_fail:
-+as_fail:
-+ dal_logger_destroy(&dc_init_data.ctx->logger);
-+logger_fail:
-+hwss_fail:
-+ dc_service_free(&ctx, dc_init_data.ctx);
-+ctx_fail:
-+ return false;
-+}
-+
-+static void destruct(struct dc *dc)
-+{
-+ destroy_links(dc);
-+ dc_service_free(dc->ctx, dc->links);
-+ dc->hwss.destruct_resource_pool(&dc->res_pool);
-+ dal_logger_destroy(&dc->ctx->logger);
-+ dc_service_free(dc->ctx, dc->ctx);
-+}
-+
-+/*******************************************************************************
-+ * Public functions
-+ ******************************************************************************/
-+
-+struct dc *dc_create(const struct dal_init_data *init_params)
-+ {
-+ struct dc_context ctx = {
-+ .driver_context = init_params->driver,
-+ .cgs_device = init_params->cgs_device
-+ };
-+ struct dc *dc = dc_service_alloc(&ctx, sizeof(*dc));
-+
-+ if (NULL == dc)
-+ goto alloc_fail;
-+
-+ ctx.dc = dc;
-+ if (false == construct(dc, init_params))
-+ goto construct_fail;
-+
-+ /*TODO: separate HW and SW initialization*/
-+ init_hw(dc);
-+
-+ return dc;
-+
-+construct_fail:
-+ dc_service_free(&ctx, dc);
-+
-+alloc_fail:
-+ return NULL;
-+}
-+
-+void dc_destroy(struct dc **dc)
-+{
-+ destruct(*dc);
-+ dc_service_free((*dc)->ctx, *dc);
-+ *dc = NULL;
-+}
-+
-+bool dc_validate_resources(
-+ const struct dc *dc,
-+ const struct dc_validation_set set[],
-+ uint8_t set_count)
-+{
-+ enum dc_status result = DC_ERROR_UNEXPECTED;
-+ struct validate_context *context;
-+
-+ context = dc_service_alloc(dc->ctx, sizeof(struct validate_context));
-+ if(context == NULL)
-+ goto context_alloc_fail;
-+
-+ result = dc->hwss.validate_with_context(dc, set, set_count, context);
-+
-+ dc_service_free(dc->ctx, context);
-+context_alloc_fail:
-+
-+ return (result == DC_OK);
-+
-+}
-+
-+static void program_timing_sync(
-+ struct dc_context *dc_ctx,
-+ struct validate_context *ctx)
-+{
-+ uint8_t i;
-+ uint8_t j;
-+ uint8_t group_size = 0;
-+ uint8_t tg_count = ctx->res_ctx.pool.controller_count;
-+ struct timing_generator *tg_set[3];
-+
-+ for (i = 0; i < tg_count; i++) {
-+ if (!ctx->res_ctx.controller_ctx[i].stream)
-+ continue;
-+
-+ tg_set[0] = ctx->res_ctx.pool.timing_generators[i];
-+ group_size = 1;
-+
-+ /* Add tg to the set, search rest of the tg's for ones with
-+ * same timing, add all tgs with same timing to the group
-+ */
-+ for (j = i + 1; j < tg_count; j++) {
-+ if (!ctx->res_ctx.controller_ctx[j].stream)
-+ continue;
-+
-+ if (is_same_timing(
-+ &ctx->res_ctx.controller_ctx[j].stream->public
-+ .timing,
-+ &ctx->res_ctx.controller_ctx[i].stream->public
-+ .timing)) {
-+ tg_set[group_size] =
-+ ctx->res_ctx.pool.timing_generators[j];
-+ group_size++;
-+ }
-+ }
-+
-+ /* Right now we limit to one timing sync group so if one is
-+ * found we break. A group has to be more than one tg.*/
-+ if (group_size > 1)
-+ break;
-+ }
-+
-+ if(group_size > 1) {
-+ dc_ctx->dc->hwss.enable_timing_synchronization(dc_ctx, group_size, tg_set);
-+ }
-+}
-+
-+static bool targets_changed(
-+ struct dc *dc,
-+ struct dc_target *targets[],
-+ uint8_t target_count)
-+{
-+ uint8_t i;
-+
-+ if (target_count != dc->current_context.target_count)
-+ return true;
-+
-+ for (i = 0; i < dc->current_context.target_count; i++) {
-+ if (&dc->current_context.targets[i]->public != targets[i])
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+static void pplib_post_set_mode(
-+ struct dc *dc,
-+ const struct validate_context *context)
-+{
-+ struct dc_pp_display_configuration pp_display_cfg = { 0 };
-+
-+ pp_display_cfg.nb_pstate_switch_disable =
-+ context->bw_results.nbp_state_change_enable == false;
-+
-+ pp_display_cfg.cpu_cc6_disable =
-+ context->bw_results.cpuc_state_change_enable == false;
-+
-+ pp_display_cfg.cpu_pstate_disable =
-+ context->bw_results.cpup_state_change_enable == false;
-+
-+ /* TODO: get cpu_pstate_separation_time from BW Calcs. */
-+ pp_display_cfg.cpu_pstate_separation_time = 0;
-+
-+ dc_service_pp_post_dce_clock_change(dc->ctx, &pp_display_cfg);
-+}
-+
-+bool dc_commit_targets(
-+ struct dc *dc,
-+ struct dc_target *targets[],
-+ uint8_t target_count)
-+{
-+ enum dc_status result = DC_ERROR_UNEXPECTED;
-+ struct validate_context *context;
-+ struct dc_validation_set set[4];
-+ uint8_t i;
-+
-+ if (false == targets_changed(dc, targets, target_count))
-+ return DC_OK;
-+
-+ dal_logger_write(dc->ctx->logger,
-+ LOG_MAJOR_INTERFACE_TRACE,
-+ LOG_MINOR_COMPONENT_DC,
-+ "%s: %d targets",
-+ __func__,
-+ target_count);
-+
-+ for (i = 0; i < target_count; i++) {
-+ struct dc_target *target = targets[i];
-+
-+ dc_target_log(target,
-+ dc->ctx->logger,
-+ LOG_MAJOR_INTERFACE_TRACE,
-+ LOG_MINOR_COMPONENT_DC);
-+
-+ set[i].target = targets[i];
-+ set[i].surface_count = 0;
-+
-+ }
-+
-+ context = dc_service_alloc(dc->ctx, sizeof(struct validate_context));
-+ if (context == NULL)
-+ goto context_alloc_fail;
-+
-+ result = dc->hwss.validate_with_context(dc, set, target_count, context);
-+ if (result != DC_OK){
-+ BREAK_TO_DEBUGGER();
-+ goto fail;
-+ }
-+
-+ if (!dal_adapter_service_is_in_accelerated_mode(
-+ dc->res_pool.adapter_srv)) {
-+ dc->hwss.enable_accelerated_mode(context);
-+ }
-+
-+ for (i = 0; i < dc->current_context.target_count; i++) {
-+ /*TODO: optimize this to happen only when necessary*/
-+ dc_target_disable_memory_requests(
-+ &dc->current_context.targets[i]->public);
-+ }
-+
-+ if (result == DC_OK) {
-+ dc->hwss.reset_hw_ctx(dc, context, target_count);
-+
-+ if (context->target_count > 0)
-+ result = dc->hwss.apply_ctx_to_hw(dc, context);
-+ }
-+
-+ for (i = 0; i < context->target_count; i++) {
-+ struct dc_target *dc_target = &context->targets[i]->public;
-+ if (context->targets[i]->status.surface_count > 0)
-+ dc_target_enable_memory_requests(dc_target);
-+ }
-+
-+ /* Release old targets */
-+ for (i = 0; i < dc->current_context.target_count; i++) {
-+ dc_target_release(
-+ &dc->current_context.targets[i]->public);
-+ dc->current_context.targets[i] = NULL;
-+ }
-+ /* Retain new targets*/
-+ for (i = 0; i < context->target_count; i++) {
-+ dc_target_retain(&context->targets[i]->public);
-+ }
-+
-+ dc->current_context = *context;
-+
-+ program_timing_sync(dc->ctx, context);
-+
-+ pplib_post_set_mode(dc, context);
-+
-+ /* TODO: disable unused plls*/
-+fail:
-+ dc_service_free(dc->ctx, context);
-+
-+context_alloc_fail:
-+ return (result == DC_OK);
-+}
-+
-+uint8_t dc_get_current_target_count(const struct dc *dc)
-+{
-+ return dc->current_context.target_count;
-+}
-+
-+struct dc_target *dc_get_target_at_index(const struct dc *dc, uint8_t i)
-+{
-+ if (i < dc->current_context.target_count)
-+ return &dc->current_context.targets[i]->public;
-+ return NULL;
-+}
-+
-+const struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index)
-+{
-+ return &dc->links[link_index]->public;
-+}
-+
-+const struct graphics_object_id dc_get_link_id_at_index(
-+ struct dc *dc, uint32_t link_index)
-+{
-+ return dc->links[link_index]->link_id;
-+}
-+
-+const struct ddc_service *dc_get_ddc_at_index(
-+ struct dc *dc, uint32_t link_index)
-+{
-+ return dc->links[link_index]->ddc;
-+}
-+
-+const enum dc_irq_source dc_get_hpd_irq_source_at_index(
-+ struct dc *dc, uint32_t link_index)
-+{
-+ return dc->links[link_index]->public.irq_source_hpd;
-+}
-+
-+const struct audio **dc_get_audios(struct dc *dc)
-+{
-+ return (const struct audio **)dc->res_pool.audios;
-+}
-+
-+void dc_get_caps(const struct dc *dc, struct dc_caps *caps)
-+{
-+ caps->max_targets = dal_min(dc->res_pool.controller_count, dc->link_count);
-+ caps->max_links = dc->link_count;
-+ caps->max_audios = dc->res_pool.audio_count;
-+}
-+
-+void dc_flip_surface_addrs(struct dc* dc,
-+ const struct dc_surface *const surfaces[],
-+ struct dc_flip_addrs flip_addrs[],
-+ uint32_t count)
-+{
-+ uint8_t i;
-+ for (i = 0; i < count; i++) {
-+ struct core_surface *surface = DC_SURFACE_TO_CORE(surfaces[i]);
-+ /*
-+ * TODO figure out a good way to keep track of address. Until
-+ * then we'll have to awkwardly bypass the "const" surface.
-+ */
-+ surface->public.address = flip_addrs[i].address;
-+ dc->hwss.update_plane_address(
-+ surface,
-+ DC_TARGET_TO_CORE(surface->status.dc_target));
-+ }
-+}
-+
-+enum dc_irq_source dc_interrupt_to_irq_source(
-+ struct dc *dc,
-+ uint32_t src_id,
-+ uint32_t ext_id)
-+{
-+ return dal_irq_service_to_irq_source(dc->res_pool.irqs, src_id, ext_id);
-+}
-+
-+
-+void dc_interrupt_set(const struct dc *dc, enum dc_irq_source src, bool enable)
-+{
-+ dal_irq_service_set(dc->res_pool.irqs, src, enable);
-+}
-+
-+void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src)
-+{
-+ dal_irq_service_ack(dc->res_pool.irqs, src);
-+}
-+
-+const struct dc_target *dc_get_target_on_irq_source(
-+ const struct dc *dc,
-+ enum dc_irq_source src)
-+{
-+ uint8_t i, j;
-+ uint8_t crtc_idx;
-+
-+ switch (src) {
-+ case DC_IRQ_SOURCE_VUPDATE1:
-+ case DC_IRQ_SOURCE_VUPDATE2:
-+ case DC_IRQ_SOURCE_VUPDATE3:
-+ case DC_IRQ_SOURCE_VUPDATE4:
-+ case DC_IRQ_SOURCE_VUPDATE5:
-+ case DC_IRQ_SOURCE_VUPDATE6:
-+ crtc_idx = src - DC_IRQ_SOURCE_VUPDATE1;
-+ break;
-+ case DC_IRQ_SOURCE_PFLIP1:
-+ case DC_IRQ_SOURCE_PFLIP2:
-+ case DC_IRQ_SOURCE_PFLIP3:
-+ case DC_IRQ_SOURCE_PFLIP4:
-+ case DC_IRQ_SOURCE_PFLIP5:
-+ case DC_IRQ_SOURCE_PFLIP6:
-+ case DC_IRQ_SOURCE_PFLIP_UNDERLAY0:
-+ crtc_idx = src - DC_IRQ_SOURCE_PFLIP1;
-+ break;
-+ default:
-+ dal_error("%s: invalid irq source: %d\n!",__func__, src);
-+ goto fail;
-+ }
-+
-+ for (i = 0; i < dc->current_context.target_count; i++) {
-+ const struct core_target *target =
-+ dc->current_context.targets[i];
-+
-+ if (NULL == target) {
-+ dal_error("%s: 'dc_target' is NULL for irq source: %d\n!",
-+ __func__, src);
-+ continue;
-+ }
-+
-+ for (j = 0; j < target->stream_count; j++) {
-+ const uint8_t controller_idx =
-+ target->streams[j]->controller_idx;
-+ if (controller_idx == crtc_idx)
-+ return &target->public;
-+ }
-+ }
-+fail:
-+ return NULL;
-+}
-+
-+void dc_set_power_state(
-+ struct dc *dc,
-+ enum dc_acpi_cm_power_state power_state,
-+ enum dc_video_power_state video_power_state)
-+{
-+ dc->previous_power_state = dc->current_power_state;
-+ dc->current_power_state = video_power_state;
-+
-+ switch (power_state) {
-+ case DC_ACPI_CM_POWER_STATE_D0:
-+ init_hw(dc);
-+ break;
-+ default:
-+ /* NULL means "reset/release all DC targets" */
-+ dc_commit_targets(dc, NULL, 0);
-+
-+ dc->hwss.power_down(&dc->current_context);
-+ break;
-+ }
-+
-+}
-+
-+void dc_resume(const struct dc *dc)
-+{
-+ uint32_t i;
-+
-+ for (i = 0; i < dc->link_count; i++)
-+ core_link_resume(dc->links[i]);
-+}
-+
-+void dc_print_sync_report(
-+ const struct dc *dc)
-+{
-+ uint32_t i;
-+ const struct core_target *core_target;
-+ struct dc_context *dc_ctx = dc->ctx;
-+ struct dc_target_sync_report *target_sync_report;
-+ struct dc_sync_report sync_report = { 0 };
-+
-+ if (dc->current_context.target_count > MAX_TARGET_NUM) {
-+ DC_ERROR("Target count: %d > %d!\n",
-+ dc->current_context.target_count,
-+ MAX_TARGET_NUM);
-+ return;
-+ }
-+
-+ sync_report.targets_num = dc->current_context.target_count;
-+
-+ /* Step 1: get data for sync validation */
-+ for (i = 0; i < dc->current_context.target_count; i++) {
-+
-+ core_target = dc->current_context.targets[i];
-+ target_sync_report = &sync_report.trg_reports[i];
-+
-+ dc->hwss.get_crtc_positions(
-+ core_target->streams[0]->tg,
-+ &target_sync_report->h_count,
-+ &target_sync_report->v_count);
-+
-+ DC_SYNC_INFO("GSL:target[%d]: h: %d\t v: %d\n",
-+ i,
-+ target_sync_report->h_count,
-+ target_sync_report->v_count);
-+ }
-+
-+ /* Step 2: validate that display pipes are synchronized (based on
-+ * data from Step 1). */
-+}
-+
-+bool dc_read_dpcd(
-+ struct dc *dc,
-+ uint32_t link_index,
-+ uint32_t address,
-+ uint8_t *data,
-+ uint32_t size)
-+{
-+ struct core_link *link =
-+ DC_LINK_TO_LINK(dc_get_link_at_index(dc, link_index));
-+ enum dc_status r = core_link_read_dpcd(link, address, data, size);
-+
-+ return r == DC_OK;
-+}
-+
-+bool dc_write_dpcd(
-+ struct dc *dc,
-+ uint32_t link_index,
-+ uint32_t address,
-+ uint8_t *data,
-+ uint32_t size)
-+{
-+ struct core_link *link =
-+ DC_LINK_TO_LINK(dc_get_link_at_index(dc, link_index));
-+ enum dc_status r = core_link_write_dpcd(link, address, data, size);
-+
-+ return r == DC_OK;
-+}
-+
-+bool dc_link_add_sink(
-+ struct dc_link *link,
-+ struct dc_sink *sink)
-+{
-+ if (link->sink_count >= MAX_SINKS_PER_LINK) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ link->sink[link->sink_count] = sink;
-+ link->sink_count++;
-+
-+ return true;
-+}
-+
-+
-+void dc_link_remove_sink(struct dc_link *link, const struct dc_sink *sink)
-+{
-+ int i;
-+
-+ if (!link->sink_count) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ for (i = 0; i < link->sink_count; i++) {
-+ if (link->sink[i] == sink) {
-+ dc_sink_release(sink);
-+ link->sink[i] = NULL;
-+ link->sink_count--;
-+ return;
-+ }
-+ }
-+
-+ BREAK_TO_DEBUGGER();
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/dal/dc/core/dc_hw_sequencer.c
-new file mode 100644
-index 0000000..b9e6ffd
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_hw_sequencer.c
-@@ -0,0 +1,49 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#include "dc_services.h"
-+#include "core_types.h"
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+#include "dce110/dce110_hw_sequencer.h"
-+#endif
-+
-+bool dc_construct_hw_sequencer(
-+ struct adapter_service *adapter_serv,
-+ struct dc *dc)
-+{
-+ enum dce_version dce_ver = dal_adapter_service_get_dce_version(adapter_serv);
-+
-+ switch (dce_ver)
-+ {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ case DCE_VERSION_11_0:
-+ return dce110_hw_sequencer_construct(dc);
-+#endif
-+ default:
-+ break;
-+ }
-+
-+ return false;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_link.c b/drivers/gpu/drm/amd/dal/dc/core/dc_link.c
-new file mode 100644
-index 0000000..a0a131e
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_link.c
-@@ -0,0 +1,1081 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dc_services.h"
-+#include "dc_helpers.h"
-+#include "dc.h"
-+#include "core_dc.h"
-+#include "adapter_service_interface.h"
-+#include "grph_object_id.h"
-+#include "connector_interface.h"
-+#include "gpio_service_interface.h"
-+#include "ddc_service_interface.h"
-+#include "core_status.h"
-+#include "dc_link_dp.h"
-+#include "link_hwss.h"
-+#include "stream_encoder_types.h"
-+#include "link_encoder_types.h"
-+#include "hw_sequencer.h"
-+
-+
-+#define LINK_INFO(...) \
-+ dal_logger_write(dc_ctx->logger, \
-+ LOG_MAJOR_HW_TRACE, LOG_MINOR_HW_TRACE_HOTPLUG, \
-+ __VA_ARGS__)
-+
-+/*******************************************************************************
-+ * Private structures
-+ ******************************************************************************/
-+
-+
-+/*******************************************************************************
-+ * Private functions
-+ ******************************************************************************/
-+static void destruct(struct core_link *link)
-+{
-+ if (link->connector)
-+ dal_connector_destroy(&link->connector);
-+
-+ if (link->ddc)
-+ dal_ddc_service_destroy(&link->ddc);
-+
-+ if(link->link_enc)
-+ link->ctx->dc->hwss.encoder_destroy(&link->link_enc);
-+}
-+
-+static bool detect_sink(struct core_link *link)
-+{
-+ uint32_t is_hpd_high = 0;
-+ struct irq *hpd_pin;
-+
-+ /* todo: may need to lock gpio access */
-+ hpd_pin = dal_adapter_service_obtain_hpd_irq(
-+ link->adapter_srv,
-+ link->link_id);
-+ if (hpd_pin == NULL)
-+ goto hpd_gpio_failure;
-+
-+ dal_irq_open(hpd_pin);
-+ dal_irq_get_value(hpd_pin, &is_hpd_high);
-+ dal_irq_close(hpd_pin);
-+ dal_adapter_service_release_irq(
-+ link->adapter_srv,
-+ hpd_pin);
-+
-+ if (is_hpd_high) {
-+ link->public.type = dc_connection_single;
-+ /* TODO: need to do the actual detection */
-+ } else {
-+ link->public.type = dc_connection_none;
-+ }
-+
-+ return true;
-+
-+hpd_gpio_failure:
-+ return false;
-+}
-+
-+
-+enum ddc_transaction_type get_ddc_transaction_type(
-+ enum signal_type sink_signal)
-+{
-+ enum ddc_transaction_type transaction_type = DDC_TRANSACTION_TYPE_NONE;
-+
-+
-+ switch (sink_signal) {
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
-+ case SIGNAL_TYPE_DVI_DUAL_LINK:
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ case SIGNAL_TYPE_LVDS:
-+ case SIGNAL_TYPE_RGB:
-+ transaction_type = DDC_TRANSACTION_TYPE_I2C;
-+ break;
-+
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_EDP:
-+ transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
-+ break;
-+
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ /* MST does not use I2COverAux, but there is the
-+ * SPECIAL use case for "immediate dwnstrm device
-+ * access" (EPR#370830). */
-+ transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+
-+ return transaction_type;
-+}
-+
-+static enum signal_type get_basic_signal_type(
-+ struct graphics_object_id encoder,
-+ struct graphics_object_id downstream)
-+{
-+ if (downstream.type == OBJECT_TYPE_CONNECTOR) {
-+ switch (downstream.id) {
-+ case CONNECTOR_ID_SINGLE_LINK_DVII:
-+ switch (encoder.id) {
-+ case ENCODER_ID_INTERNAL_DAC1:
-+ case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
-+ case ENCODER_ID_INTERNAL_DAC2:
-+ case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
-+ return SIGNAL_TYPE_RGB;
-+ default:
-+ return SIGNAL_TYPE_DVI_SINGLE_LINK;
-+ }
-+ break;
-+ case CONNECTOR_ID_DUAL_LINK_DVII:
-+ {
-+ switch (encoder.id) {
-+ case ENCODER_ID_INTERNAL_DAC1:
-+ case ENCODER_ID_INTERNAL_KLDSCP_DAC1:
-+ case ENCODER_ID_INTERNAL_DAC2:
-+ case ENCODER_ID_INTERNAL_KLDSCP_DAC2:
-+ return SIGNAL_TYPE_RGB;
-+ default:
-+ return SIGNAL_TYPE_DVI_DUAL_LINK;
-+ }
-+ }
-+ break;
-+ case CONNECTOR_ID_SINGLE_LINK_DVID:
-+ return SIGNAL_TYPE_DVI_SINGLE_LINK;
-+ case CONNECTOR_ID_DUAL_LINK_DVID:
-+ return SIGNAL_TYPE_DVI_DUAL_LINK;
-+ case CONNECTOR_ID_VGA:
-+ return SIGNAL_TYPE_RGB;
-+ case CONNECTOR_ID_HDMI_TYPE_A:
-+ return SIGNAL_TYPE_HDMI_TYPE_A;
-+ case CONNECTOR_ID_LVDS:
-+ return SIGNAL_TYPE_LVDS;
-+ case CONNECTOR_ID_DISPLAY_PORT:
-+ return SIGNAL_TYPE_DISPLAY_PORT;
-+ case CONNECTOR_ID_EDP:
-+ return SIGNAL_TYPE_EDP;
-+ default:
-+ return SIGNAL_TYPE_NONE;
-+ }
-+ } else if (downstream.type == OBJECT_TYPE_ENCODER) {
-+ switch (downstream.id) {
-+ case ENCODER_ID_EXTERNAL_NUTMEG:
-+ case ENCODER_ID_EXTERNAL_TRAVIS:
-+ return SIGNAL_TYPE_DISPLAY_PORT;
-+ default:
-+ return SIGNAL_TYPE_NONE;
-+ }
-+ }
-+
-+ return SIGNAL_TYPE_NONE;
-+}
-+
-+/*
-+ * @brief
-+ * Check whether there is a dongle on DP connector
-+ */
-+static bool is_dp_sink_present(struct core_link *link)
-+{
-+ enum gpio_result gpio_result;
-+ uint32_t clock_pin = 0;
-+ uint32_t data_pin = 0;
-+
-+ struct ddc *ddc;
-+
-+ enum connector_id connector_id =
-+ dal_graphics_object_id_get_connector_id(link->link_id);
-+
-+ bool present =
-+ ((connector_id == CONNECTOR_ID_DISPLAY_PORT) ||
-+ (connector_id == CONNECTOR_ID_EDP));
-+
-+ ddc = dal_adapter_service_obtain_ddc(link->adapter_srv, link->link_id);
-+
-+ if (!ddc)
-+ return present;
-+
-+ /* Open GPIO and set it to I2C mode */
-+ /* Note: this GpioMode_Input will be converted
-+ * to GpioConfigType_I2cAuxDualMode in GPIO component,
-+ * which indicates we need additional delay */
-+
-+ if (GPIO_RESULT_OK != dal_ddc_open(
-+ ddc, GPIO_MODE_INPUT, GPIO_DDC_CONFIG_TYPE_MODE_I2C)) {
-+ dal_adapter_service_release_ddc(link->adapter_srv, ddc);
-+
-+ return present;
-+ }
-+
-+ /* Read GPIO: DP sink is present if both clock and data pins are zero */
-+ /* [anaumov] in DAL2, there was no check for GPIO failure */
-+
-+ gpio_result = dal_ddc_get_clock(ddc, &clock_pin);
-+ ASSERT(gpio_result == GPIO_RESULT_OK);
-+
-+ if (gpio_result == GPIO_RESULT_OK)
-+ if (link->link_enc->features.flags.bits.
-+ DP_SINK_DETECT_POLL_DATA_PIN)
-+ gpio_result = dal_ddc_get_data(ddc, &data_pin);
-+
-+ present = (gpio_result == GPIO_RESULT_OK) && !(clock_pin || data_pin);
-+
-+ dal_ddc_close(ddc);
-+
-+ dal_adapter_service_release_ddc(link->adapter_srv, ddc);
-+
-+ return present;
-+}
-+
-+/*
-+ * @brief
-+ * Detect output sink type
-+ */
-+static enum signal_type link_detect_sink(struct core_link *link)
-+{
-+ enum signal_type result = get_basic_signal_type(
-+ link->link_enc->id, link->link_id);
-+
-+ /* Internal digital encoder will detect only dongles
-+ * that require digital signal */
-+
-+ /* Detection mechanism is different
-+ * for different native connectors.
-+ * LVDS connector supports only LVDS signal;
-+ * PCIE is a bus slot, the actual connector needs to be detected first;
-+ * eDP connector supports only eDP signal;
-+ * HDMI should check straps for audio */
-+
-+ /* PCIE detects the actual connector on add-on board */
-+
-+ if (link->link_id.id == CONNECTOR_ID_PCIE) {
-+ /* ZAZTODO implement PCIE add-on card detection */
-+ }
-+
-+ switch (link->link_id.id) {
-+ case CONNECTOR_ID_HDMI_TYPE_A: {
-+ /* check audio support:
-+ * if native HDMI is not supported, switch to DVI */
-+ union audio_support audio_support =
-+ dal_adapter_service_get_audio_support(
-+ link->adapter_srv);
-+
-+ if (!audio_support.bits.HDMI_AUDIO_NATIVE)
-+ if (link->link_id.id == CONNECTOR_ID_HDMI_TYPE_A)
-+ result = SIGNAL_TYPE_DVI_SINGLE_LINK;
-+ }
-+ break;
-+ case CONNECTOR_ID_DISPLAY_PORT: {
-+
-+ /* Check whether DP signal detected: if not -
-+ * we assume signal is DVI; it could be corrected
-+ * to HDMI after dongle detection */
-+ if (!is_dp_sink_present(link))
-+ result = SIGNAL_TYPE_DVI_SINGLE_LINK;
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return result;
-+}
-+
-+static enum signal_type decide_signal_from_strap_and_dongle_type(
-+ enum display_dongle_type dongle_type,
-+ union audio_support *audio_support)
-+{
-+ enum signal_type signal = SIGNAL_TYPE_NONE;
-+
-+ switch (dongle_type) {
-+ case DISPLAY_DONGLE_DP_HDMI_DONGLE:
-+ if (audio_support->bits.HDMI_AUDIO_ON_DONGLE)
-+ signal = SIGNAL_TYPE_HDMI_TYPE_A;
-+ else
-+ signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
-+ break;
-+ case DISPLAY_DONGLE_DP_DVI_DONGLE:
-+ signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
-+ break;
-+ case DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE:
-+ if (audio_support->bits.HDMI_AUDIO_NATIVE)
-+ signal = SIGNAL_TYPE_HDMI_TYPE_A;
-+ else
-+ signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
-+ break;
-+ default:
-+ signal = SIGNAL_TYPE_NONE;
-+ break;
-+ }
-+
-+ return signal;
-+}
-+
-+static enum signal_type dp_passive_dongle_detection(
-+ struct ddc_service *ddc,
-+ struct display_sink_capability *sink_cap,
-+ union audio_support *audio_support)
-+{
-+ /* TODO:These 2 functions should be protected for upstreaming purposes
-+ * in case hackers want to save 10 cents hdmi license fee
-+ */
-+ dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
-+ ddc, sink_cap);
-+ return decide_signal_from_strap_and_dongle_type(
-+ sink_cap->dongle_type,
-+ audio_support);
-+}
-+
-+static bool is_dp_active_dongle(enum display_dongle_type dongle_type)
-+{
-+ return (dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER ||
-+ dongle_type == DISPLAY_DONGLE_DP_DVI_CONVERTER ||
-+ dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER);
-+}
-+
-+/* TODO: To beretired because this call is wrong with
-+ * pluging in of active-dongle without display*/
-+static void link_unplug(struct core_link *link)
-+{
-+ int i;
-+
-+ for (i = 0; i < link->public.sink_count; i++)
-+ dc_link_remove_sink(&link->public, link->public.sink[i]);
-+}
-+
-+static enum dc_edid_status read_edid(struct core_link *link)
-+{
-+ uint32_t edid_retry = 3;
-+ enum dc_edid_status edid_status;
-+ const struct dc_sink *dc_sink = link->public.sink[0];
-+ struct core_sink *sink = DC_SINK_TO_CORE(dc_sink);
-+
-+ if (link->public.sink[0]->sink_signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_DETECTION_EDID_PARSER,
-+ "MST EDID read is not done here!\n");
-+ return EDID_BAD_INPUT;
-+ }
-+
-+ /* some dongles read edid incorrectly the first time,
-+ * do check sum and retry to make sure read correct edid.
-+ */
-+ do {
-+ sink->public.dc_edid.length =
-+ dal_ddc_service_edid_query(link->ddc);
-+
-+ if (0 == sink->public.dc_edid.length)
-+ return EDID_NO_RESPONSE;
-+
-+ dal_ddc_service_get_edid_buf(link->ddc,
-+ sink->public.dc_edid.raw_edid);
-+ edid_status = dc_helpers_parse_edid_caps(
-+ link->ctx,
-+ &sink->public.dc_edid,
-+ &sink->public.edid_caps);
-+ --edid_retry;
-+ if (edid_status == EDID_BAD_CHECKSUM)
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_DETECTION_EDID_PARSER,
-+ "Bad EDID checksum, retry remain: %d\n",
-+ edid_retry);
-+ } while (edid_status == EDID_BAD_CHECKSUM && edid_retry > 0);
-+
-+ return edid_status;
-+}
-+
-+void dc_link_detect(const struct dc_link *dc_link)
-+{
-+ struct core_link *link = DC_LINK_TO_LINK(dc_link);
-+ struct sink_init_data sink_init_data = { 0 };
-+ enum ddc_transaction_type transaction_type = DDC_TRANSACTION_TYPE_NONE;
-+ struct display_sink_capability sink_caps = { 0 };
-+ uint8_t i;
-+ enum signal_type signal = SIGNAL_TYPE_NONE;
-+ bool converter_disable_audio = false;
-+ union audio_support audio_support =
-+ dal_adapter_service_get_audio_support(
-+ link->adapter_srv);
-+ enum dc_edid_status edid_status;
-+ struct dc_context *dc_ctx = link->ctx;
-+ struct dc_sink *dc_sink;
-+ struct core_sink *sink = NULL;
-+
-+ if (false == detect_sink(link)) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ if (link->public.type != dc_connection_none) {
-+ /* From Disconnected-to-Connected. */
-+ switch (link->public.connector_signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A: {
-+ transaction_type = DDC_TRANSACTION_TYPE_I2C;
-+ if (audio_support.bits.HDMI_AUDIO_NATIVE)
-+ signal = SIGNAL_TYPE_HDMI_TYPE_A;
-+ else
-+ signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
-+ break;
-+ }
-+
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK: {
-+ transaction_type = DDC_TRANSACTION_TYPE_I2C;
-+ signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
-+ break;
-+ }
-+
-+ case SIGNAL_TYPE_DVI_DUAL_LINK: {
-+ transaction_type = DDC_TRANSACTION_TYPE_I2C;
-+ signal = SIGNAL_TYPE_DVI_DUAL_LINK;
-+ break;
-+ }
-+
-+ case SIGNAL_TYPE_EDP: {
-+ detect_dp_sink_caps(link);
-+ transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
-+ signal = SIGNAL_TYPE_EDP;
-+ break;
-+ }
-+
-+ case SIGNAL_TYPE_DISPLAY_PORT: {
-+ signal = link_detect_sink(link);
-+ transaction_type = get_ddc_transaction_type(
-+ signal);
-+
-+ if (transaction_type ==
-+ DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
-+ signal =
-+ SIGNAL_TYPE_DISPLAY_PORT;
-+ detect_dp_sink_caps(link);
-+
-+ /* DP active dongles */
-+ if (is_dp_active_dongle(
-+ link->dpcd_caps.dongle_type)) {
-+ if (!link->dpcd_caps.
-+ sink_count.bits.SINK_COUNT) {
-+ link->public.type =
-+ dc_connection_none;
-+ /* active dongle unplug
-+ * processing for short irq
-+ */
-+ link_unplug(link);
-+ return;
-+ }
-+
-+ if (link->dpcd_caps.dongle_type !=
-+ DISPLAY_DONGLE_DP_HDMI_CONVERTER) {
-+ converter_disable_audio = true;
-+ }
-+ }
-+ if (is_mst_supported(link)) {
-+ signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
-+
-+ /*
-+ * This call will initiate MST topology
-+ * discovery. Which will detect
-+ * MST ports and add new DRM connector
-+ * DRM framework. Then read EDID via
-+ * remote i2c over aux.In the end, will
-+ * notify DRM detect result and save
-+ * EDID into DRM framework.
-+ *
-+ * .detect is called by .fill_modes.
-+ * .fill_modes is called by user mode
-+ * ioctl DRM_IOCTL_MODE_GETCONNECTOR.
-+ *
-+ * .get_modes is called by .fill_modes.
-+ *
-+ * call .get_modes, AMDGPU DM
-+ * implementation will create new
-+ * dc_sink and add to dc_link.
-+ * For long HPD plug in/out, MST has its
-+ * own handle.
-+ *
-+ * Therefore, just after dc_create,
-+ * link->sink is not created for MST
-+ * until user mode app calls
-+ * DRM_IOCTL_MODE_GETCONNECTOR.
-+ *
-+ * Need check ->sink usages in case
-+ * ->sink = NULL
-+ * TODO: s3 resume check*/
-+
-+ if (dc_helpers_dp_mst_start_top_mgr(link->ctx, &link->public)) {
-+ return;
-+ } else {
-+ /* MST not supported */
-+ signal = SIGNAL_TYPE_DISPLAY_PORT;
-+ }
-+ }
-+ }
-+ else {
-+ /* DP passive dongles */
-+ signal = dp_passive_dongle_detection(link->ddc,
-+ &sink_caps,
-+ &audio_support);
-+ }
-+ break;
-+ }
-+
-+ default:
-+ DC_ERROR("Invalid connector type! signal:%d\n",
-+ link->public.connector_signal);
-+ return;
-+ } /* switch() */
-+
-+ if (link->dpcd_caps.sink_count.bits.SINK_COUNT)
-+ link->dpcd_sink_count = link->dpcd_caps.sink_count.
-+ bits.SINK_COUNT;
-+ else
-+ link->dpcd_sink_count = 1;
-+
-+
-+ dal_ddc_service_set_transaction_type(
-+ link->ddc,
-+ transaction_type);
-+
-+ sink_init_data.link = &link->public;
-+ sink_init_data.sink_signal = signal;
-+ sink_init_data.dongle_max_pix_clk =
-+ sink_caps.max_hdmi_pixel_clock;
-+ sink_init_data.converter_disable_audio =
-+ converter_disable_audio;
-+
-+ dc_sink = sink_create(&sink_init_data);
-+ if (!dc_sink) {
-+ DC_ERROR("Failed to create sink!\n");
-+ return;
-+ }
-+
-+ sink = DC_SINK_TO_CORE(dc_sink);
-+
-+ /*AG TODO handle failure */
-+ /*Only non MST case here */
-+ if (!dc_link_add_sink(&link->public, &sink->public))
-+ BREAK_TO_DEBUGGER();
-+
-+ edid_status = read_edid(link);
-+
-+ switch (edid_status) {
-+ case EDID_BAD_CHECKSUM:
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_DETECTION_EDID_PARSER,
-+ "EDID checksum invalid.\n");
-+ break;
-+ case EDID_NO_RESPONSE:
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_DETECTION_EDID_PARSER,
-+ "No EDID read.\n");
-+ return;
-+
-+ default:
-+ break;
-+ }
-+
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_DETECTION,
-+ LOG_MINOR_DETECTION_EDID_PARSER,
-+ "%s: "
-+ "manufacturer_id = %X, "
-+ "product_id = %X, "
-+ "serial_number = %X, "
-+ "manufacture_week = %d, "
-+ "manufacture_year = %d, "
-+ "display_name = %s, "
-+ "speaker_flag = %d, "
-+ "audio_mode_count = %d\n",
-+ __func__,
-+ sink->public.edid_caps.manufacturer_id,
-+ sink->public.edid_caps.product_id,
-+ sink->public.edid_caps.serial_number,
-+ sink->public.edid_caps.manufacture_week,
-+ sink->public.edid_caps.manufacture_year,
-+ sink->public.edid_caps.display_name,
-+ sink->public.edid_caps.speaker_flags,
-+ sink->public.edid_caps.audio_mode_count);
-+
-+ for (i = 0; i < sink->public.edid_caps.audio_mode_count; i++) {
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_DETECTION,
-+ LOG_MINOR_DETECTION_EDID_PARSER,
-+ "%s: mode number = %d, "
-+ "format_code = %d, "
-+ "channel_count = %d, "
-+ "sample_rate = %d, "
-+ "sample_size = %d\n",
-+ __func__,
-+ i,
-+ sink->public.edid_caps.audio_modes[i].format_code,
-+ sink->public.edid_caps.audio_modes[i].channel_count,
-+ sink->public.edid_caps.audio_modes[i].sample_rate,
-+ sink->public.edid_caps.audio_modes[i].sample_size);
-+ }
-+
-+ } else {
-+ /* From Connected-to-Disconnected. */
-+ switch (link->public.connector_signal) {
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ dc_helpers_dp_mst_stop_top_mgr(link->ctx, &link->public);
-+ break;
-+ default:
-+ break;
-+ }
-+ link_unplug(link);
-+ }
-+
-+ LINK_INFO("link=%d, dc_sink_in=%p is now %s\n",
-+ link->link_index, &sink->public,
-+ (signal == SIGNAL_TYPE_NONE ? "Disconnected":"Connected"));
-+
-+ /* TODO: */
-+
-+ return;
-+}
-+
-+static bool construct(
-+ struct core_link *link,
-+ const struct link_init_data *init_params)
-+{
-+ struct irq *hpd_gpio = NULL;
-+ struct ddc_service_init_data ddc_service_init_data = { 0 };
-+ struct dc_context *dc_ctx = init_params->ctx;
-+ struct encoder_init_data enc_init_data = { 0 };
-+ struct connector_feature_support cfs = { 0 };
-+
-+ link->dc = init_params->dc;
-+ link->adapter_srv = init_params->adapter_srv;
-+ link->connector_index = init_params->connector_index;
-+ link->ctx = dc_ctx;
-+ link->link_index = init_params->link_index;
-+
-+ link->link_id = dal_adapter_service_get_connector_obj_id(
-+ init_params->adapter_srv,
-+ init_params->connector_index);
-+
-+ if (link->link_id.type != OBJECT_TYPE_CONNECTOR) {
-+ dal_error("%s: Invalid Connector ObjectID from Adapter Service for connector index:%d!\n",
-+ __func__, init_params->connector_index);
-+ goto create_fail;
-+ }
-+
-+ switch (link->link_id.id) {
-+ case CONNECTOR_ID_HDMI_TYPE_A:
-+ link->public.connector_signal = SIGNAL_TYPE_HDMI_TYPE_A;
-+ break;
-+ case CONNECTOR_ID_SINGLE_LINK_DVID:
-+ case CONNECTOR_ID_SINGLE_LINK_DVII:
-+ link->public.connector_signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
-+ break;
-+ case CONNECTOR_ID_DUAL_LINK_DVID:
-+ case CONNECTOR_ID_DUAL_LINK_DVII:
-+ link->public.connector_signal = SIGNAL_TYPE_DVI_DUAL_LINK;
-+ break;
-+ case CONNECTOR_ID_DISPLAY_PORT:
-+ link->public.connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
-+ hpd_gpio = dal_adapter_service_obtain_hpd_irq(
-+ init_params->adapter_srv,
-+ link->link_id);
-+
-+ if (hpd_gpio != NULL) {
-+ link->public.irq_source_hpd_rx =
-+ dal_irq_get_rx_source(hpd_gpio);
-+ dal_adapter_service_release_irq(
-+ init_params->adapter_srv, hpd_gpio);
-+ }
-+ break;
-+ case CONNECTOR_ID_EDP:
-+ link->public.connector_signal = SIGNAL_TYPE_EDP;
-+ hpd_gpio = dal_adapter_service_obtain_hpd_irq(
-+ init_params->adapter_srv,
-+ link->link_id);
-+
-+ if (hpd_gpio != NULL) {
-+ link->public.irq_source_hpd_rx =
-+ dal_irq_get_rx_source(hpd_gpio);
-+ dal_adapter_service_release_irq(
-+ init_params->adapter_srv, hpd_gpio);
-+ }
-+ break;
-+ default:
-+ dal_logger_write(dc_ctx->logger,
-+ LOG_MAJOR_WARNING, LOG_MINOR_TM_LINK_SRV,
-+ "Unsupported Connector type:%d!\n", link->link_id.id);
-+ goto create_fail;
-+ }
-+
-+ /* TODO: #DAL3 Implement id to str function.*/
-+ LINK_INFO("Connector[%d] description:\n",
-+ init_params->connector_index);
-+
-+ link->connector = dal_connector_create(dc_ctx,
-+ init_params->adapter_srv,
-+ link->link_id);
-+ if (NULL == link->connector) {
-+ DC_ERROR("Failed to create connector object!\n");
-+ goto create_fail;
-+ }
-+
-+
-+ hpd_gpio = dal_adapter_service_obtain_hpd_irq(
-+ init_params->adapter_srv,
-+ link->link_id);
-+
-+ if (hpd_gpio != NULL) {
-+ link->public.irq_source_hpd = dal_irq_get_source(hpd_gpio);
-+ dal_adapter_service_release_irq(
-+ init_params->adapter_srv, hpd_gpio);
-+ }
-+
-+ ddc_service_init_data.as = link->adapter_srv;
-+ ddc_service_init_data.ctx = link->ctx;
-+ ddc_service_init_data.id = link->link_id;
-+ link->ddc = dal_ddc_service_create(&ddc_service_init_data);
-+
-+ if (NULL == link->ddc) {
-+ DC_ERROR("Failed to create ddc_service!\n");
-+ goto create_fail;
-+ }
-+
-+ dal_connector_get_features(link->connector, &cfs);
-+
-+ enc_init_data.adapter_service = link->adapter_srv;
-+ enc_init_data.ctx = dc_ctx;
-+ enc_init_data.encoder = dal_adapter_service_get_src_obj(
-+ link->adapter_srv, link->link_id, 0);
-+ enc_init_data.connector = link->link_id;
-+ enc_init_data.channel = cfs.ddc_line;
-+ enc_init_data.hpd_source = cfs.hpd_line;
-+ link->link_enc = dc_ctx->dc->hwss.encoder_create(&enc_init_data);
-+
-+ if( link->link_enc == NULL) {
-+ DC_ERROR("Failed to create link encoder!\n");
-+ goto create_fail;
-+ }
-+
-+ /*
-+ * TODO check if GPIO programmed correctly
-+ *
-+ * If GPIO isn't programmed correctly HPD might not rise or drain
-+ * fast enough, leading to bounces.
-+ */
-+#define DELAY_ON_CONNECT_IN_MS 500
-+#define DELAY_ON_DISCONNECT_IN_MS 500
-+
-+ dal_connector_program_hpd_filter(
-+ link->connector,
-+ DELAY_ON_CONNECT_IN_MS,
-+ DELAY_ON_DISCONNECT_IN_MS);
-+
-+ return true;
-+
-+create_fail:
-+ return false;
-+}
-+
-+/*******************************************************************************
-+ * Public functions
-+ ******************************************************************************/
-+struct core_link *link_create(const struct link_init_data *init_params)
-+{
-+ struct core_link *link =
-+ dc_service_alloc(init_params->ctx, sizeof(*link));
-+ link->ctx = init_params->ctx;
-+
-+ if (NULL == link)
-+ goto alloc_fail;
-+
-+ if (false == construct(link, init_params))
-+ goto construct_fail;
-+
-+ return link;
-+
-+construct_fail:
-+ dc_service_free(init_params->ctx, link);
-+
-+alloc_fail:
-+ return NULL;
-+}
-+
-+void link_destroy(struct core_link **link)
-+{
-+ destruct(*link);
-+ dc_service_free((*link)->ctx, *link);
-+ *link = NULL;
-+}
-+
-+static void dpcd_configure_panel_mode(
-+ struct core_link *link,
-+ enum dp_panel_mode panel_mode)
-+{
-+ union dpcd_edp_config edp_config_set;
-+ bool panel_mode_edp = false;
-+
-+ dc_service_memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config));
-+
-+ if (DP_PANEL_MODE_DEFAULT != panel_mode) {
-+
-+ switch (panel_mode) {
-+ case DP_PANEL_MODE_EDP:
-+ case DP_PANEL_MODE_SPECIAL:
-+ panel_mode_edp = true;
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ /*set edp panel mode in receiver*/
-+ core_link_read_dpcd(
-+ link,
-+ DPCD_ADDRESS_EDP_CONFIG_SET,
-+ &edp_config_set.raw,
-+ sizeof(edp_config_set.raw));
-+
-+ if (edp_config_set.bits.PANEL_MODE_EDP
-+ != panel_mode_edp) {
-+ enum ddc_result result = DDC_RESULT_UNKNOWN;
-+
-+ edp_config_set.bits.PANEL_MODE_EDP =
-+ panel_mode_edp;
-+ result = core_link_write_dpcd(
-+ link,
-+ DPCD_ADDRESS_EDP_CONFIG_SET,
-+ &edp_config_set.raw,
-+ sizeof(edp_config_set.raw));
-+
-+ ASSERT(result == DDC_RESULT_SUCESSFULL);
-+ }
-+ }
-+ dal_logger_write(link->ctx->logger, LOG_MAJOR_DETECTION,
-+ LOG_MINOR_DETECTION_DP_CAPS,
-+ "Connector: %d eDP panel mode supported: %d "
-+ "eDP panel mode enabled: %d \n",
-+ link->connector_index,
-+ link->dpcd_caps.panel_mode_edp,
-+ panel_mode_edp);
-+}
-+
-+static enum dc_status enable_link_dp(struct core_stream *stream)
-+{
-+ enum dc_status status;
-+ bool skip_video_pattern;
-+ struct core_link *link = stream->sink->link;
-+ struct link_settings link_settings = {0};
-+ enum dp_panel_mode panel_mode;
-+
-+ /* get link settings for video mode timing */
-+ decide_link_settings(stream, &link_settings);
-+ status = dp_enable_link_phy(
-+ stream->sink->link,
-+ stream->signal,
-+ stream->stream_enc->id,
-+ &link_settings);
-+
-+ panel_mode = dp_get_panel_mode(link);
-+ dpcd_configure_panel_mode(link, panel_mode);
-+
-+ skip_video_pattern = true;
-+
-+ if (link_settings.link_rate == LINK_RATE_LOW)
-+ skip_video_pattern = false;
-+
-+ if (perform_link_training(link, &link_settings, skip_video_pattern)) {
-+ link->cur_link_settings = link_settings;
-+ status = DC_OK;
-+ }
-+ else
-+ status = DC_ERROR_UNEXPECTED;
-+
-+ return status;
-+}
-+
-+static enum dc_status enable_link_hdmi(struct core_stream *stream)
-+{
-+ struct core_link *link = stream->sink->link;
-+
-+ /* TODO:Need to add missing use cases, reference
-+ * dal_hw_sequencer_enable_link_base*/
-+ enum dc_status status = DC_OK;
-+
-+ /* enable video output */
-+ /* here we need to specify that encoder output settings
-+ * need to be calculated as for the set mode,
-+ * it will lead to querying dynamic link capabilities
-+ * which should be done before enable output */
-+
-+ uint32_t normalized_pix_clk = stream->public.timing.pix_clk_khz;
-+ switch (stream->public.timing.display_color_depth) {
-+ case COLOR_DEPTH_888:
-+ break;
-+ case COLOR_DEPTH_101010:
-+ normalized_pix_clk = (normalized_pix_clk * 30) / 24;
-+ break;
-+ case COLOR_DEPTH_121212:
-+ normalized_pix_clk = (normalized_pix_clk * 36) / 24;
-+ break;
-+ case COLOR_DEPTH_161616:
-+ normalized_pix_clk = (normalized_pix_clk * 48) / 24;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-+ dal_ddc_service_write_scdc_data(
-+ stream->sink->link->ddc,
-+ normalized_pix_clk,
-+ stream->public.timing.flags.LTE_340MCSC_SCRAMBLE);
-+
-+ stream->sink->link->cur_link_settings.lane_count =
-+ (stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK)
-+ ? LANE_COUNT_EIGHT : LANE_COUNT_FOUR;
-+
-+ if (link->ctx->dc->hwss.encoder_enable_output(
-+ stream->sink->link->link_enc,
-+ &stream->sink->link->cur_link_settings,
-+ stream->stream_enc->id,
-+ dal_clock_source_get_id(stream->clock_source),
-+ stream->signal,
-+ stream->public.timing.display_color_depth,
-+ stream->public.timing.pix_clk_khz) != ENCODER_RESULT_OK)
-+ status = DC_ERROR_UNEXPECTED;
-+
-+ if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-+ dal_ddc_service_read_scdc_data(link->ddc);
-+
-+ return status;
-+}
-+
-+/****************************enable_link***********************************/
-+enum dc_status core_link_enable(struct core_stream *stream)
-+{
-+ enum dc_status status;
-+ switch (stream->signal) {
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_EDP:
-+ status = enable_link_dp(stream);
-+ break;
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
-+ case SIGNAL_TYPE_DVI_DUAL_LINK:
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ status = enable_link_hdmi(stream);
-+ break;
-+
-+ default:
-+ status = DC_ERROR_UNEXPECTED;
-+ break;
-+ }
-+
-+ if (stream->audio) {
-+ stream->ctx->dc->hwss.set_afmt_memory_power_state(
-+ stream->ctx, stream->stream_enc->id, true);
-+ /* notify audio driver for audio modes of monitor */
-+ dal_audio_enable_azalia_audio_jack_presence(stream->audio,
-+ stream->stream_enc->id);
-+
-+ /* un-mute audio */
-+ dal_audio_unmute(stream->audio, stream->stream_enc->id,
-+ stream->signal);
-+ }
-+
-+ return status;
-+}
-+
-+enum dc_status core_link_disable(struct core_stream *stream)
-+{
-+ /* TODO dp_set_hw_test_pattern */
-+ enum dc_status status = DC_OK;
-+ struct dc *dc = stream->ctx->dc;
-+
-+ /* here we need to specify that encoder output settings
-+ * need to be calculated as for the set mode,
-+ * it will lead to querying dynamic link capabilities
-+ * which should be done before enable output */
-+
-+ if (dc_is_dp_signal(stream->signal))
-+ dp_disable_link_phy(stream->sink->link, stream->signal);
-+ else if (ENCODER_RESULT_OK != dc->hwss.encoder_disable_output(
-+ stream->sink->link->link_enc, stream->signal))
-+ status = DC_ERROR_UNEXPECTED;
-+
-+ if (stream->audio) {
-+ dc->hwss.set_afmt_memory_power_state(
-+ stream->ctx, stream->stream_enc->id, false);
-+ }
-+
-+ return status;
-+}
-+
-+enum dc_status dc_link_validate_mode_timing(
-+ const struct core_sink *sink,
-+ struct core_link *link,
-+ const struct dc_crtc_timing *timing)
-+{
-+ uint32_t max_pix_clk = sink->dongle_max_pix_clk;
-+
-+ if (0 != max_pix_clk && timing->pix_clk_khz > max_pix_clk)
-+ return DC_EXCEED_DONGLE_MAX_CLK;
-+
-+ switch (sink->public.sink_signal) {
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ if(!dp_validate_mode_timing(
-+ link,
-+ timing))
-+ return DC_NO_DP_LINK_BANDWIDTH;
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ return DC_OK;
-+}
-+
-+bool dc_link_set_backlight_level(const struct dc_link *public, uint32_t level)
-+{
-+ struct core_link *protected = DC_LINK_TO_CORE(public);
-+ struct dc_context *ctx = protected->ctx;
-+
-+ dal_logger_write(ctx->logger, LOG_MAJOR_BACKLIGHT,
-+ LOG_MINOR_BACKLIGHT_INTERFACE,
-+ "New Backlight level: %d (0x%X)\n", level, level);
-+
-+ ctx->dc->hwss.encoder_set_lcd_backlight_level(protected->link_enc, level);
-+
-+ return true;
-+}
-+
-+void core_link_resume(struct core_link *link)
-+{
-+ dal_connector_program_hpd_filter(
-+ link->connector,
-+ DELAY_ON_CONNECT_IN_MS,
-+ DELAY_ON_DISCONNECT_IN_MS);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/dal/dc/core/dc_link_dp.c
-new file mode 100644
-index 0000000..9214aec
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_link_dp.c
-@@ -0,0 +1,1689 @@
-+/* Copyright 2015 Advanced Micro Devices, Inc. */
-+#include "dc_services.h"
-+#include "dc.h"
-+#include "dc_helpers.h"
-+#include "inc/core_types.h"
-+#include "link_hwss.h"
-+#include "ddc_service_interface.h"
-+#include "connector_interface.h"
-+#include "core_status.h"
-+#include "dpcd_defs.h"
-+
-+/* maximum pre emphasis level allowed for each voltage swing level*/
-+static const enum pre_emphasis voltage_swing_to_pre_emphasis[] = {
-+ PRE_EMPHASIS_LEVEL3,
-+ PRE_EMPHASIS_LEVEL2,
-+ PRE_EMPHASIS_LEVEL1,
-+ PRE_EMPHASIS_DISABLED };
-+
-+enum {
-+ POST_LT_ADJ_REQ_LIMIT = 6,
-+ POST_LT_ADJ_REQ_TIMEOUT = 200
-+};
-+
-+enum {
-+ LINK_TRAINING_MAX_RETRY_COUNT = 5,
-+ /* to avoid infinite loop where-in the receiver
-+ * switches between different VS
-+ */
-+ LINK_TRAINING_MAX_CR_RETRY = 100
-+};
-+
-+static const struct link_settings link_training_fallback_table[] = {
-+/* 2160 Mbytes/sec*/
-+{ LANE_COUNT_FOUR, LINK_RATE_HIGH2, LINK_SPREAD_DISABLED },
-+/* 1080 Mbytes/sec*/
-+{ LANE_COUNT_FOUR, LINK_RATE_HIGH, LINK_SPREAD_DISABLED },
-+/* 648 Mbytes/sec*/
-+{ LANE_COUNT_FOUR, LINK_RATE_LOW, LINK_SPREAD_DISABLED },
-+/* 1080 Mbytes/sec*/
-+{ LANE_COUNT_TWO, LINK_RATE_HIGH2, LINK_SPREAD_DISABLED },
-+/* 540 Mbytes/sec*/
-+{ LANE_COUNT_TWO, LINK_RATE_HIGH, LINK_SPREAD_DISABLED },
-+/* 324 Mbytes/sec*/
-+{ LANE_COUNT_TWO, LINK_RATE_LOW, LINK_SPREAD_DISABLED },
-+/* 540 Mbytes/sec*/
-+{ LANE_COUNT_ONE, LINK_RATE_HIGH2, LINK_SPREAD_DISABLED },
-+/* 270 Mbytes/sec*/
-+{ LANE_COUNT_ONE, LINK_RATE_HIGH, LINK_SPREAD_DISABLED },
-+/* 162 Mbytes/sec*/
-+{ LANE_COUNT_ONE, LINK_RATE_LOW, LINK_SPREAD_DISABLED } };
-+
-+static void wait_for_training_aux_rd_interval(
-+ struct core_link* link,
-+ uint32_t default_wait_in_micro_secs)
-+{
-+ uint8_t training_rd_interval;
-+
-+ /* overwrite the delay if rev > 1.1*/
-+ if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
-+ /* DP 1.2 or later - retrieve delay through
-+ * "DPCD_ADDR_TRAINING_AUX_RD_INTERVAL" register */
-+ core_link_read_dpcd(
-+ link,
-+ DPCD_ADDRESS_TRAINING_AUX_RD_INTERVAL,
-+ &training_rd_interval,
-+ sizeof(training_rd_interval));
-+ default_wait_in_micro_secs = training_rd_interval ?
-+ (training_rd_interval * 4000) :
-+ default_wait_in_micro_secs;
-+ }
-+
-+ dc_service_delay_in_microseconds(link->ctx, default_wait_in_micro_secs);
-+
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_LINK_TRAINING,
-+ "%s:\n wait = %d\n",
-+ __func__,
-+ default_wait_in_micro_secs);
-+}
-+
-+static void dpcd_set_training_pattern(
-+ struct core_link* link,
-+ union dpcd_training_pattern dpcd_pattern)
-+{
-+ core_link_write_dpcd(
-+ link,
-+ DPCD_ADDRESS_TRAINING_PATTERN_SET,
-+ &dpcd_pattern.raw,
-+ 1);
-+
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_LINK_TRAINING,
-+ "%s\n %x pattern = %x\n",
-+ __func__,
-+ DPCD_ADDRESS_TRAINING_PATTERN_SET,
-+ dpcd_pattern.bits.TRAINING_PATTERN_SET);
-+}
-+
-+static void dpcd_set_link_settings(
-+ struct core_link* link,
-+ const struct link_training_settings *lt_settings)
-+{
-+ uint8_t rate = (uint8_t)
-+ (lt_settings->link_settings.link_rate);
-+
-+ union down_spread_ctrl downspread = {{0}};
-+ union lane_count_set lane_count_set = {{0}};
-+ uint8_t link_set_buffer[2];
-+
-+
-+ downspread.raw = (uint8_t)
-+ (lt_settings->link_settings.link_spread);
-+
-+ lane_count_set.bits.LANE_COUNT_SET =
-+ lt_settings->link_settings.lane_count;
-+
-+ lane_count_set.bits.ENHANCED_FRAMING = 1;
-+
-+ lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED =
-+ link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED;
-+
-+ link_set_buffer[0] = rate;
-+ link_set_buffer[1] = lane_count_set.raw;
-+
-+ core_link_write_dpcd(link, DPCD_ADDRESS_LINK_BW_SET,
-+ link_set_buffer, 2);
-+ core_link_write_dpcd(link, DPCD_ADDRESS_DOWNSPREAD_CNTL,
-+ &downspread.raw, sizeof(downspread));
-+
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_LINK_TRAINING,
-+ "%s\n %x rate = %x\n %x lane = %x\n %x spread = %x\n",
-+ __func__,
-+ DPCD_ADDRESS_LINK_BW_SET,
-+ lt_settings->link_settings.link_rate,
-+ DPCD_ADDRESS_LANE_COUNT_SET,
-+ lt_settings->link_settings.lane_count,
-+ DPCD_ADDRESS_DOWNSPREAD_CNTL,
-+ lt_settings->link_settings.link_spread);
-+
-+}
-+
-+static enum dpcd_training_patterns
-+ hw_training_pattern_to_dpcd_training_pattern(
-+ struct core_link* link,
-+ enum hw_dp_training_pattern pattern)
-+{
-+ enum dpcd_training_patterns dpcd_tr_pattern =
-+ DPCD_TRAINING_PATTERN_VIDEOIDLE;
-+
-+ switch (pattern) {
-+ case HW_DP_TRAINING_PATTERN_1:
-+ dpcd_tr_pattern = DPCD_TRAINING_PATTERN_1;
-+ break;
-+ case HW_DP_TRAINING_PATTERN_2:
-+ dpcd_tr_pattern = DPCD_TRAINING_PATTERN_2;
-+ break;
-+ case HW_DP_TRAINING_PATTERN_3:
-+ dpcd_tr_pattern = DPCD_TRAINING_PATTERN_3;
-+ break;
-+ default:
-+ ASSERT(0);
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_LINK_TRAINING,
-+ "%s: Invalid HW Training pattern: %d\n",
-+ __func__, pattern);
-+ break;
-+ }
-+
-+ return dpcd_tr_pattern;
-+
-+}
-+
-+static void dpcd_set_lt_pattern_and_lane_settings(
-+ struct core_link* link,
-+ const struct link_training_settings *lt_settings,
-+ enum hw_dp_training_pattern pattern)
-+{
-+ union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = {{{0}}};
-+ const uint32_t dpcd_base_lt_offset =
-+ DPCD_ADDRESS_TRAINING_PATTERN_SET;
-+ uint8_t dpcd_lt_buffer[5] = {0};
-+ union dpcd_training_pattern dpcd_pattern = {{0}};
-+ uint32_t lane;
-+ uint32_t size_in_bytes;
-+ bool edp_workaround = false; /* TODO link_prop.INTERNAL */
-+
-+ /*****************************************************************
-+ * DpcdAddress_TrainingPatternSet
-+ *****************************************************************/
-+ dpcd_pattern.bits.TRAINING_PATTERN_SET =
-+ hw_training_pattern_to_dpcd_training_pattern(link, pattern);
-+
-+ dpcd_lt_buffer[DPCD_ADDRESS_TRAINING_PATTERN_SET - dpcd_base_lt_offset]
-+ = dpcd_pattern.raw;
-+
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_LINK_TRAINING,
-+ "%s\n %x pattern = %x\n",
-+ __func__,
-+ DPCD_ADDRESS_TRAINING_PATTERN_SET,
-+ dpcd_pattern.bits.TRAINING_PATTERN_SET);
-+
-+
-+ /*****************************************************************
-+ * DpcdAddress_Lane0Set -> DpcdAddress_Lane3Set
-+ *****************************************************************/
-+ for (lane = 0; lane <
-+ (uint32_t)(lt_settings->link_settings.lane_count); lane++) {
-+
-+ dpcd_lane[lane].bits.VOLTAGE_SWING_SET =
-+ (uint8_t)(lt_settings->lane_settings[lane].VOLTAGE_SWING);
-+ dpcd_lane[lane].bits.PRE_EMPHASIS_SET =
-+ (uint8_t)(lt_settings->lane_settings[lane].PRE_EMPHASIS);
-+
-+ dpcd_lane[lane].bits.MAX_SWING_REACHED =
-+ (lt_settings->lane_settings[lane].VOLTAGE_SWING ==
-+ VOLTAGE_SWING_MAX_LEVEL ? 1 : 0);
-+ dpcd_lane[lane].bits.MAX_PRE_EMPHASIS_REACHED =
-+ (lt_settings->lane_settings[lane].PRE_EMPHASIS ==
-+ PRE_EMPHASIS_MAX_LEVEL ? 1 : 0);
-+ }
-+
-+ /* concatinate everything into one buffer*/
-+
-+ size_in_bytes = lt_settings->link_settings.lane_count * sizeof(dpcd_lane[0]);
-+
-+ // 0x00103 - 0x00102
-+ dc_service_memmove(
-+ &dpcd_lt_buffer[DPCD_ADDRESS_LANE0_SET - dpcd_base_lt_offset],
-+ dpcd_lane,
-+ size_in_bytes);
-+
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_LINK_TRAINING,
-+ "%s:\n %x VS set = %x PE set = %x \
-+ max VS Reached = %x max PE Reached = %x\n",
-+ __func__,
-+ DPCD_ADDRESS_LANE0_SET,
-+ dpcd_lane[0].bits.VOLTAGE_SWING_SET,
-+ dpcd_lane[0].bits.PRE_EMPHASIS_SET,
-+ dpcd_lane[0].bits.MAX_SWING_REACHED,
-+ dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
-+
-+
-+ if (edp_workaround) {
-+ /* for eDP write in 2 parts because the 5-byte burst is
-+ * causing issues on some eDP panels (EPR#366724)
-+ */
-+ core_link_write_dpcd(
-+ link,
-+ DPCD_ADDRESS_TRAINING_PATTERN_SET,
-+ &dpcd_pattern.raw,
-+ sizeof(dpcd_pattern.raw) );
-+
-+ core_link_write_dpcd(
-+ link,
-+ DPCD_ADDRESS_LANE0_SET,
-+ (uint8_t *)(dpcd_lane),
-+ size_in_bytes);
-+
-+ } else
-+ /* write it all in (1 + number-of-lanes)-byte burst*/
-+ core_link_write_dpcd(
-+ link,
-+ dpcd_base_lt_offset,
-+ dpcd_lt_buffer,
-+ size_in_bytes + sizeof(dpcd_pattern.raw) );
-+
-+ link->ln_setting = lt_settings->lane_settings[0];
-+}
-+
-+static bool is_cr_done(enum lane_count ln_count,
-+ union lane_status *dpcd_lane_status)
-+{
-+ bool done = true;
-+ uint32_t lane;
-+ /*LANEx_CR_DONE bits All 1's?*/
-+ for (lane = 0; lane < (uint32_t)(ln_count); lane++) {
-+ if (!dpcd_lane_status[lane].bits.CR_DONE_0)
-+ done = false;
-+ }
-+ return done;
-+
-+}
-+
-+static bool is_ch_eq_done(enum lane_count ln_count,
-+ union lane_status *dpcd_lane_status,
-+ union lane_align_status_updated *lane_status_updated)
-+{
-+ bool done = true;
-+ uint32_t lane;
-+ if (!lane_status_updated->bits.INTERLANE_ALIGN_DONE)
-+ done = false;
-+ else {
-+ for (lane = 0; lane < (uint32_t)(ln_count); lane++) {
-+ if (!dpcd_lane_status[lane].bits.SYMBOL_LOCKED_0 ||
-+ !dpcd_lane_status[lane].bits.CHANNEL_EQ_DONE_0)
-+ done = false;
-+ }
-+ }
-+ return done;
-+
-+}
-+
-+static void update_drive_settings(
-+ struct link_training_settings *dest,
-+ struct link_training_settings src)
-+{
-+ uint32_t lane;
-+ for (lane = 0; lane < src.link_settings.lane_count; lane++) {
-+ dest->lane_settings[lane].VOLTAGE_SWING =
-+ src.lane_settings[lane].VOLTAGE_SWING;
-+ dest->lane_settings[lane].PRE_EMPHASIS =
-+ src.lane_settings[lane].PRE_EMPHASIS;
-+ dest->lane_settings[lane].POST_CURSOR2 =
-+ src.lane_settings[lane].POST_CURSOR2;
-+ }
-+}
-+
-+static uint8_t get_nibble_at_index(const uint8_t *buf,
-+ uint32_t index)
-+{
-+ uint8_t nibble;
-+ nibble = buf[index / 2];
-+
-+ if (index % 2)
-+ nibble >>= 4;
-+ else
-+ nibble &= 0x0F;
-+
-+ return nibble;
-+}
-+
-+static enum pre_emphasis get_max_pre_emphasis_for_voltage_swing(
-+ enum voltage_swing voltage)
-+{
-+ enum pre_emphasis pre_emphasis;
-+ pre_emphasis = PRE_EMPHASIS_MAX_LEVEL;
-+
-+ if (voltage <= VOLTAGE_SWING_MAX_LEVEL)
-+ pre_emphasis = voltage_swing_to_pre_emphasis[voltage];
-+
-+ return pre_emphasis;
-+
-+}
-+
-+static void find_max_drive_settings(
-+ const struct link_training_settings *link_training_setting,
-+ struct link_training_settings *max_lt_setting)
-+{
-+ uint32_t lane;
-+ struct lane_settings max_requested;
-+
-+ max_requested.VOLTAGE_SWING =
-+ link_training_setting->
-+ lane_settings[0].VOLTAGE_SWING;
-+ max_requested.PRE_EMPHASIS =
-+ link_training_setting->
-+ lane_settings[0].PRE_EMPHASIS;
-+ /*max_requested.postCursor2 =
-+ * link_training_setting->laneSettings[0].postCursor2;*/
-+
-+ /* Determine what the maximum of the requested settings are*/
-+ for (lane = 1; lane < link_training_setting->link_settings.lane_count;
-+ lane++) {
-+ if (link_training_setting->lane_settings[lane].VOLTAGE_SWING >
-+ max_requested.VOLTAGE_SWING)
-+
-+ max_requested.VOLTAGE_SWING =
-+ link_training_setting->
-+ lane_settings[lane].VOLTAGE_SWING;
-+
-+
-+ if (link_training_setting->lane_settings[lane].PRE_EMPHASIS >
-+ max_requested.PRE_EMPHASIS)
-+ max_requested.PRE_EMPHASIS =
-+ link_training_setting->
-+ lane_settings[lane].PRE_EMPHASIS;
-+
-+ /*
-+ if (link_training_setting->laneSettings[lane].postCursor2 >
-+ max_requested.postCursor2)
-+ {
-+ max_requested.postCursor2 =
-+ link_training_setting->laneSettings[lane].postCursor2;
-+ }
-+ */
-+ }
-+
-+ /* make sure the requested settings are
-+ * not higher than maximum settings*/
-+ if (max_requested.VOLTAGE_SWING > VOLTAGE_SWING_MAX_LEVEL)
-+ max_requested.VOLTAGE_SWING = VOLTAGE_SWING_MAX_LEVEL;
-+
-+ if (max_requested.PRE_EMPHASIS > PRE_EMPHASIS_MAX_LEVEL)
-+ max_requested.PRE_EMPHASIS = PRE_EMPHASIS_MAX_LEVEL;
-+ /*
-+ if (max_requested.postCursor2 > PostCursor2_MaxLevel)
-+ max_requested.postCursor2 = PostCursor2_MaxLevel;
-+ */
-+
-+ /* make sure the pre-emphasis matches the voltage swing*/
-+ if (max_requested.PRE_EMPHASIS >
-+ get_max_pre_emphasis_for_voltage_swing(
-+ max_requested.VOLTAGE_SWING))
-+ max_requested.PRE_EMPHASIS =
-+ get_max_pre_emphasis_for_voltage_swing(
-+ max_requested.VOLTAGE_SWING);
-+
-+ /*
-+ * Post Cursor2 levels are completely independent from
-+ * pre-emphasis (Post Cursor1) levels. But Post Cursor2 levels
-+ * can only be applied to each allowable combination of voltage
-+ * swing and pre-emphasis levels */
-+ /* if ( max_requested.postCursor2 >
-+ * getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing))
-+ * max_requested.postCursor2 =
-+ * getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing);
-+ */
-+
-+ max_lt_setting->link_settings.link_rate =
-+ link_training_setting->link_settings.link_rate;
-+ max_lt_setting->link_settings.lane_count =
-+ link_training_setting->link_settings.lane_count;
-+ max_lt_setting->link_settings.link_spread =
-+ link_training_setting->link_settings.link_spread;
-+
-+ for (lane = 0; lane <
-+ link_training_setting->link_settings.lane_count;
-+ lane++) {
-+ max_lt_setting->lane_settings[lane].VOLTAGE_SWING =
-+ max_requested.VOLTAGE_SWING;
-+ max_lt_setting->lane_settings[lane].PRE_EMPHASIS =
-+ max_requested.PRE_EMPHASIS;
-+ /*max_lt_setting->laneSettings[lane].postCursor2 =
-+ * max_requested.postCursor2;
-+ */
-+ }
-+
-+}
-+
-+static void get_lane_status_and_drive_settings(
-+ struct core_link* link,
-+ const struct link_training_settings *link_training_setting,
-+ union lane_status *ln_status,
-+ union lane_align_status_updated *ln_status_updated,
-+ struct link_training_settings *req_settings)
-+{
-+ uint8_t dpcd_buf[6] = {0};
-+ union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {{{0}}};
-+ struct link_training_settings request_settings = {{0}};
-+ uint32_t lane;
-+
-+ dc_service_memset(req_settings, '\0', sizeof(struct link_training_settings));
-+
-+ core_link_read_dpcd(
-+ link,
-+ DPCD_ADDRESS_LANE_01_STATUS,
-+ (uint8_t *)(dpcd_buf),
-+ sizeof(dpcd_buf));
-+
-+
-+ for (lane = 0; lane <
-+ (uint32_t)(link_training_setting->link_settings.lane_count);
-+ lane++) {
-+
-+ ln_status[lane].raw =
-+ get_nibble_at_index(&dpcd_buf[0], lane);
-+ dpcd_lane_adjust[lane].raw =
-+ get_nibble_at_index(&dpcd_buf[4], lane);
-+ }
-+
-+ ln_status_updated->raw = dpcd_buf[2];
-+
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_LINK_TRAINING,
-+ "%s:\n%x Lane01Status = %x\n %x Lane23Status = %x\n ",
-+ __func__,
-+ DPCD_ADDRESS_LANE_01_STATUS, dpcd_buf[0],
-+ DPCD_ADDRESS_LANE_23_STATUS, dpcd_buf[1]);
-+
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_LINK_TRAINING,
-+ "%s:\n %x Lane01AdjustRequest = %x\n %x Lane23AdjustRequest = %x\n",
-+ __func__,
-+ DPCD_ADDRESS_ADJUST_REQUEST_LANE0_1,
-+ dpcd_buf[4],
-+ DPCD_ADDRESS_ADJUST_REQUEST_LANE2_3,
-+ dpcd_buf[5]);
-+
-+ /*copy to req_settings*/
-+ request_settings.link_settings.lane_count =
-+ link_training_setting->link_settings.lane_count;
-+ request_settings.link_settings.link_rate =
-+ link_training_setting->link_settings.link_rate;
-+ request_settings.link_settings.link_spread =
-+ link_training_setting->link_settings.link_spread;
-+
-+ for (lane = 0; lane <
-+ (uint32_t)(link_training_setting->link_settings.lane_count);
-+ lane++) {
-+
-+ request_settings.lane_settings[lane].VOLTAGE_SWING =
-+ (enum voltage_swing)(dpcd_lane_adjust[lane].bits.
-+ VOLTAGE_SWING_LANE);
-+ request_settings.lane_settings[lane].PRE_EMPHASIS =
-+ (enum pre_emphasis)(dpcd_lane_adjust[lane].bits.
-+ PRE_EMPHASIS_LANE);
-+ }
-+
-+ /*Note: for postcursor2, read adjusted
-+ * postcursor2 settings from*/
-+ /*DpcdAddress_AdjustRequestPostCursor2 =
-+ *0x020C (not implemented yet)*/
-+
-+ /* we find the maximum of the requested settings across all lanes*/
-+ /* and set this maximum for all lanes*/
-+ find_max_drive_settings(&request_settings, req_settings);
-+
-+ /* if post cursor 2 is needed in the future,
-+ * read DpcdAddress_AdjustRequestPostCursor2 = 0x020C
-+ */
-+
-+}
-+
-+static void dpcd_set_lane_settings(
-+ struct core_link* link,
-+ const struct link_training_settings *link_training_setting)
-+{
-+ union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = {{{0}}};
-+ uint32_t lane;
-+
-+ for (lane = 0; lane <
-+ (uint32_t)(link_training_setting->
-+ link_settings.lane_count);
-+ lane++) {
-+ dpcd_lane[lane].bits.VOLTAGE_SWING_SET =
-+ (uint8_t)(link_training_setting->
-+ lane_settings[lane].VOLTAGE_SWING);
-+ dpcd_lane[lane].bits.PRE_EMPHASIS_SET =
-+ (uint8_t)(link_training_setting->
-+ lane_settings[lane].PRE_EMPHASIS);
-+ dpcd_lane[lane].bits.MAX_SWING_REACHED =
-+ (link_training_setting->
-+ lane_settings[lane].VOLTAGE_SWING ==
-+ VOLTAGE_SWING_MAX_LEVEL ? 1 : 0);
-+ dpcd_lane[lane].bits.MAX_PRE_EMPHASIS_REACHED =
-+ (link_training_setting->
-+ lane_settings[lane].PRE_EMPHASIS ==
-+ PRE_EMPHASIS_MAX_LEVEL ? 1 : 0);
-+ }
-+
-+ core_link_write_dpcd(link,
-+ DPCD_ADDRESS_LANE0_SET,
-+ (uint8_t *)(dpcd_lane),
-+ link_training_setting->link_settings.lane_count);
-+
-+ /*
-+ if (LTSettings.link.rate == LinkRate_High2)
-+ {
-+ DpcdTrainingLaneSet2 dpcd_lane2[lane_count_DPMax] = {0};
-+ for ( uint32_t lane = 0;
-+ lane < lane_count_DPMax; lane++)
-+ {
-+ dpcd_lane2[lane].bits.post_cursor2_set =
-+ static_cast<unsigned char>(
-+ LTSettings.laneSettings[lane].postCursor2);
-+ dpcd_lane2[lane].bits.max_post_cursor2_reached = 0;
-+ }
-+ m_pDpcdAccessSrv->WriteDpcdData(
-+ DpcdAddress_Lane0Set2,
-+ reinterpret_cast<unsigned char*>(dpcd_lane2),
-+ LTSettings.link.lanes);
-+ }
-+ */
-+
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_LINK_TRAINING,
-+ "%s\n %x VS set = %x PE set = %x \
-+ max VS Reached = %x max PE Reached = %x\n",
-+ __func__,
-+ DPCD_ADDRESS_LANE0_SET,
-+ dpcd_lane[0].bits.VOLTAGE_SWING_SET,
-+ dpcd_lane[0].bits.PRE_EMPHASIS_SET,
-+ dpcd_lane[0].bits.MAX_SWING_REACHED,
-+ dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
-+
-+ link->ln_setting = link_training_setting->lane_settings[0];
-+
-+}
-+
-+static bool is_max_vs_reached(
-+ const struct link_training_settings *lt_settings)
-+{
-+ uint32_t lane;
-+ for (lane = 0; lane <
-+ (uint32_t)(lt_settings->link_settings.lane_count);
-+ lane++) {
-+ if (lt_settings->lane_settings[lane].VOLTAGE_SWING
-+ == VOLTAGE_SWING_MAX_LEVEL)
-+ return true;
-+ }
-+ return false;
-+
-+}
-+
-+void set_drive_settings(
-+ struct core_link *link,
-+ struct link_training_settings *lt_settings)
-+{
-+ /* program ASIC PHY settings*/
-+ dp_set_hw_lane_settings(link, lt_settings);
-+
-+ /* Notify DP sink the PHY settings from source */
-+ dpcd_set_lane_settings(link, lt_settings);
-+}
-+
-+static bool perform_post_lt_adj_req_sequence(
-+ struct core_link *link,
-+ struct link_training_settings *lt_settings)
-+{
-+ enum lane_count lane_count =
-+ lt_settings->link_settings.lane_count;
-+
-+ uint32_t adj_req_count;
-+ uint32_t adj_req_timer;
-+ bool req_drv_setting_changed;
-+ uint32_t lane;
-+
-+ req_drv_setting_changed = false;
-+ for (adj_req_count = 0; adj_req_count < POST_LT_ADJ_REQ_LIMIT;
-+ adj_req_count++) {
-+
-+ req_drv_setting_changed = false;
-+
-+ for (adj_req_timer = 0;
-+ adj_req_timer < POST_LT_ADJ_REQ_TIMEOUT;
-+ adj_req_timer++) {
-+
-+ struct link_training_settings req_settings;
-+ union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
-+ union lane_align_status_updated
-+ dpcd_lane_status_updated;
-+
-+ get_lane_status_and_drive_settings(
-+ link,
-+ lt_settings,
-+ dpcd_lane_status,
-+ &dpcd_lane_status_updated,
-+ &req_settings);
-+
-+ if (dpcd_lane_status_updated.bits.
-+ POST_LT_ADJ_REQ_IN_PROGRESS == 0)
-+ return true;
-+
-+ if (!is_cr_done(lane_count, dpcd_lane_status))
-+ return false;
-+
-+ if (!is_ch_eq_done(
-+ lane_count,
-+ dpcd_lane_status,
-+ &dpcd_lane_status_updated))
-+ return false;
-+
-+ for (lane = 0; lane < (uint32_t)(lane_count); lane++) {
-+
-+ if (lt_settings->
-+ lane_settings[lane].VOLTAGE_SWING !=
-+ req_settings.lane_settings[lane].
-+ VOLTAGE_SWING ||
-+ lt_settings->lane_settings[lane].PRE_EMPHASIS !=
-+ req_settings.lane_settings[lane].PRE_EMPHASIS) {
-+
-+ req_drv_setting_changed = true;
-+ break;
-+ }
-+ }
-+
-+ if (req_drv_setting_changed) {
-+ update_drive_settings(
-+ lt_settings,req_settings);
-+
-+ set_drive_settings(link, lt_settings);
-+ break;
-+ }
-+
-+ dc_service_sleep_in_milliseconds(link->ctx, 1);
-+ }
-+
-+ if (!req_drv_setting_changed) {
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_LINK_SERVICE,
-+ "%s: Post Link Training Adjust Request Timed out\n",
-+ __func__);
-+
-+ ASSERT(0);
-+ return true;
-+ }
-+ }
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_LINK_SERVICE,
-+ "%s: Post Link Training Adjust Request limit reached\n",
-+ __func__);
-+
-+ ASSERT(0);
-+ return true;
-+
-+}
-+
-+static bool perform_channel_equalization_sequence(
-+ struct core_link *link,
-+ struct link_training_settings *lt_settings)
-+{
-+ struct link_training_settings req_settings;
-+ enum hw_dp_training_pattern hw_tr_pattern;
-+ uint32_t retries_ch_eq;
-+ enum lane_count lane_count = lt_settings->link_settings.lane_count;
-+ union lane_align_status_updated dpcd_lane_status_updated = {{0}};
-+ union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {{{0}}};;
-+
-+ /*TODO hw_tr_pattern = HW_DP_TRAINING_PATTERN_3;*/
-+ hw_tr_pattern = HW_DP_TRAINING_PATTERN_2;
-+
-+ dp_set_hw_training_pattern(link, hw_tr_pattern);
-+
-+ for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT;
-+ retries_ch_eq++) {
-+
-+ dp_set_hw_lane_settings(link, lt_settings);
-+
-+ /* 2. update DPCD*/
-+ if (!retries_ch_eq)
-+ /* EPR #361076 - write as a 5-byte burst,
-+ * but only for the 1-st iteration*/
-+ dpcd_set_lt_pattern_and_lane_settings(
-+ link,
-+ lt_settings,
-+ hw_tr_pattern);
-+ else
-+ dpcd_set_lane_settings(link, lt_settings);
-+
-+ /* 3. wait for receiver to lock-on*/
-+ wait_for_training_aux_rd_interval(link, 400);
-+
-+ /* 4. Read lane status and requested
-+ * drive settings as set by the sink*/
-+
-+ get_lane_status_and_drive_settings(
-+ link,
-+ lt_settings,
-+ dpcd_lane_status,
-+ &dpcd_lane_status_updated,
-+ &req_settings);
-+
-+ /* 5. check CR done*/
-+ if (!is_cr_done(lane_count, dpcd_lane_status))
-+ return false;
-+
-+ /* 6. check CHEQ done*/
-+ if (is_ch_eq_done(lane_count,
-+ dpcd_lane_status,
-+ &dpcd_lane_status_updated))
-+ return true;
-+
-+ /* 7. update VS/PE/PC2 in lt_settings*/
-+ update_drive_settings(lt_settings, req_settings);
-+ }
-+
-+ return false;
-+
-+}
-+
-+static bool perform_clock_recovery_sequence(
-+ struct core_link *link,
-+ struct link_training_settings *lt_settings)
-+{
-+ uint32_t retries_cr;
-+ uint32_t retry_count;
-+ uint32_t lane;
-+ struct link_training_settings req_settings;
-+ enum lane_count lane_count =
-+ lt_settings->link_settings.lane_count;
-+ enum hw_dp_training_pattern hw_tr_pattern = HW_DP_TRAINING_PATTERN_1;
-+ union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
-+ union lane_align_status_updated dpcd_lane_status_updated;
-+
-+ retries_cr = 0;
-+ retry_count = 0;
-+ /* initial drive setting (VS/PE/PC2)*/
-+ for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
-+ lt_settings->lane_settings[lane].VOLTAGE_SWING =
-+ VOLTAGE_SWING_LEVEL0;
-+ lt_settings->lane_settings[lane].PRE_EMPHASIS =
-+ PRE_EMPHASIS_DISABLED;
-+ lt_settings->lane_settings[lane].POST_CURSOR2 =
-+ POST_CURSOR2_DISABLED;
-+ }
-+
-+ dp_set_hw_training_pattern(link, hw_tr_pattern);
-+
-+ /* najeeb - The synaptics MST hub can put the LT in
-+ * infinite loop by switching the VS
-+ */
-+ /* between level 0 and level 1 continuously, here
-+ * we try for CR lock for LinkTrainingMaxCRRetry count*/
-+ while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) &&
-+ (retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
-+
-+ dc_service_memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status));
-+ dc_service_memset(&dpcd_lane_status_updated, '\0',
-+ sizeof(dpcd_lane_status_updated));
-+
-+ /* 1. call HWSS to set lane settings*/
-+ dp_set_hw_lane_settings(
-+ link,
-+ lt_settings);
-+
-+ /* 2. update DPCD of the receiver*/
-+ if (!retries_cr)
-+ /* EPR #361076 - write as a 5-byte burst,
-+ * but only for the 1-st iteration.*/
-+ dpcd_set_lt_pattern_and_lane_settings(
-+ link,
-+ lt_settings,
-+ hw_tr_pattern);
-+ else
-+ dpcd_set_lane_settings(
-+ link,
-+ lt_settings);
-+
-+
-+ /* 3. wait receiver to lock-on*/
-+ wait_for_training_aux_rd_interval(
-+ link,
-+ 100);
-+
-+ /* 4. Read lane status and requested drive
-+ * settings as set by the sink
-+ */
-+ get_lane_status_and_drive_settings(
-+ link,
-+ lt_settings,
-+ dpcd_lane_status,
-+ &dpcd_lane_status_updated,
-+ &req_settings);
-+
-+
-+ /* 5. check CR done*/
-+ if (is_cr_done(lane_count, dpcd_lane_status))
-+ return true;
-+
-+ /* 6. max VS reached*/
-+ if (is_max_vs_reached(lt_settings))
-+ return false;
-+
-+ /* 7. same voltage*/
-+ /* Note: VS same for all lanes,
-+ * so comparing first lane is sufficient*/
-+ if (lt_settings->lane_settings[0].VOLTAGE_SWING ==
-+ req_settings.lane_settings[0].VOLTAGE_SWING)
-+ retries_cr++;
-+ else
-+ retries_cr = 0;
-+
-+
-+ /* 8. update VS/PE/PC2 in lt_settings*/
-+ update_drive_settings(lt_settings, req_settings);
-+
-+ retry_count++;
-+ }
-+
-+ if (retry_count >= LINK_TRAINING_MAX_CR_RETRY) {
-+ ASSERT(0);
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_LINK_SERVICE,
-+ "%s: Link Training Error, could not \
-+ get CR after %d tries. \
-+ Possibly voltage swing issue", __func__,
-+ LINK_TRAINING_MAX_CR_RETRY);
-+
-+ }
-+
-+ return false;
-+}
-+
-+ bool perform_link_training(
-+ struct core_link *link,
-+ const struct link_settings *link_setting,
-+ bool skip_video_pattern)
-+{
-+ bool status;
-+ union dpcd_training_pattern dpcd_pattern = {{0}};
-+ union lane_count_set lane_count_set = {{0}};
-+ const int8_t *link_rate = "Unknown";
-+ struct link_training_settings lt_settings;
-+
-+ status = false;
-+ dc_service_memset(&lt_settings, '\0', sizeof(lt_settings));
-+
-+ lt_settings.link_settings.link_rate = link_setting->link_rate;
-+ lt_settings.link_settings.lane_count = link_setting->lane_count;
-+
-+ /*@todo[vdevulap] move SS to LS, should not be handled by displaypath*/
-+
-+ /* TODO hard coded to SS for now
-+ * lt_settings.link_settings.link_spread =
-+ * dal_display_path_is_ss_supported(
-+ * path_mode->display_path) ?
-+ * LINK_SPREAD_05_DOWNSPREAD_30KHZ :
-+ * LINK_SPREAD_DISABLED;
-+ */
-+ lt_settings.link_settings.link_spread = LINK_SPREAD_05_DOWNSPREAD_30KHZ;
-+
-+ /* 1. set link rate, lane count and spread*/
-+ dpcd_set_link_settings(link, &lt_settings);
-+
-+ /* 2. perform link training (set link training done
-+ * to false is done as well)*/
-+ if (perform_clock_recovery_sequence(link, &lt_settings)) {
-+
-+ if (perform_channel_equalization_sequence(link, &lt_settings))
-+ status = true;
-+ }
-+
-+ if (status || !skip_video_pattern) {
-+
-+ /* 3. set training not in progress*/
-+ dpcd_pattern.bits.TRAINING_PATTERN_SET =
-+ DPCD_TRAINING_PATTERN_VIDEOIDLE;
-+ dpcd_set_training_pattern(link, dpcd_pattern);
-+
-+ /* 4. mainlink output idle pattern*/
-+ dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE);
-+
-+ /* 5. post training adjust if required*/
-+ if (link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED
-+ == 1) {
-+ if (status == true) {
-+ if (perform_post_lt_adj_req_sequence(
-+ link, &lt_settings) == false)
-+ status = false;
-+ }
-+
-+ lane_count_set.bits.LANE_COUNT_SET =
-+ lt_settings.link_settings.lane_count;
-+ lane_count_set.bits.ENHANCED_FRAMING = 1;
-+ lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
-+
-+ core_link_write_dpcd(
-+ link,
-+ DPCD_ADDRESS_LANE_COUNT_SET,
-+ &lane_count_set.raw,
-+ sizeof(lane_count_set));
-+ }
-+ }
-+
-+ /* 6. print status message*/
-+ switch (lt_settings.link_settings.link_rate) {
-+
-+ case LINK_RATE_LOW:
-+ link_rate = "Low";
-+ break;
-+ case LINK_RATE_HIGH:
-+ link_rate = "High";
-+ break;
-+ case LINK_RATE_HIGH2:
-+ link_rate = "High2";
-+ break;
-+ case LINK_RATE_RBR2:
-+ link_rate = "RBR2";
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_MST,
-+ LOG_MINOR_MST_PROGRAMMING,
-+ "Link training for %d lanes at %s rate %s\n",
-+ lt_settings.link_settings.lane_count,
-+ link_rate,
-+ status ? "succeeded" : "failed");
-+
-+ return status;
-+}
-+
-+/*TODO add more check to see if link support request link configuration */
-+static bool is_link_setting_supported(
-+ const struct link_settings *link_setting,
-+ const struct link_settings *max_link_setting)
-+{
-+ if (link_setting->lane_count > max_link_setting->lane_count ||
-+ link_setting->link_rate > max_link_setting->link_rate)
-+ return false;
-+ return true;
-+}
-+
-+static const uint32_t get_link_training_fallback_table_len(
-+ struct core_link *link)
-+{
-+ return ARRAY_SIZE(link_training_fallback_table);
-+}
-+
-+static const struct link_settings *get_link_training_fallback_table(
-+ struct core_link *link, uint32_t i)
-+{
-+ return &link_training_fallback_table[i];
-+}
-+
-+static bool exceeded_limit_link_setting(const struct link_settings *link_setting,
-+ const struct link_settings *limit_link_setting)
-+{
-+ return (link_setting->lane_count * link_setting->link_rate
-+ > limit_link_setting->lane_count * limit_link_setting->link_rate ?
-+ true : false);
-+}
-+
-+
-+bool dp_hbr_verify_link_cap(
-+ struct core_link *link,
-+ struct link_settings *known_limit_link_setting)
-+{
-+ struct link_settings max_link_cap = {0};
-+ bool success;
-+ bool skip_link_training;
-+ const struct link_settings *cur;
-+ bool skip_video_pattern;
-+ uint32_t i;
-+
-+ success = false;
-+ skip_link_training = false;
-+
-+ /* TODO confirm this is correct for cz */
-+ max_link_cap.lane_count = LANE_COUNT_FOUR;
-+ max_link_cap.link_rate = LINK_RATE_HIGH2;
-+ max_link_cap.link_spread = LINK_SPREAD_05_DOWNSPREAD_30KHZ;
-+
-+ /* TODO implement override and monitor patch later */
-+
-+ /* try to train the link from high to low to
-+ * find the physical link capability
-+ */
-+ /* disable PHY done possible by BIOS, will be done by driver itself */
-+ dp_disable_link_phy(link, link->public.connector_signal);
-+
-+ for (i = 0; i < get_link_training_fallback_table_len(link) &&
-+ !success; i++) {
-+ cur = get_link_training_fallback_table(link, i);
-+
-+ if (known_limit_link_setting->lane_count != LANE_COUNT_UNKNOWN &&
-+ exceeded_limit_link_setting(cur,
-+ known_limit_link_setting))
-+ continue;
-+
-+ if (!is_link_setting_supported(cur, &max_link_cap))
-+ continue;
-+
-+ skip_video_pattern = true;
-+ if (cur->link_rate == LINK_RATE_LOW)
-+ skip_video_pattern = false;
-+ if (dp_enable_link_phy(
-+ link,
-+ link->public.connector_signal,
-+ ENGINE_ID_UNKNOWN,
-+ cur)) {
-+ if (skip_link_training)
-+ success = true;
-+ else {
-+ uint8_t num_retries = 3;
-+ uint8_t j;
-+ uint8_t delay_between_retries = 10;
-+ for (j = 0; j < num_retries; ++j) {
-+ success = perform_link_training(
-+ link,
-+ cur,
-+ skip_video_pattern);
-+
-+ if (success)
-+ break;
-+
-+ dc_service_sleep_in_milliseconds(
-+ link->ctx,
-+ delay_between_retries);
-+
-+ delay_between_retries += 10;
-+ }
-+ }
-+ }
-+
-+ if (success)
-+ link->verified_link_cap = *cur;
-+
-+ /* always disable the link before trying another
-+ * setting or before returning we'll enable it later
-+ * based on the actual mode we're driving
-+ */
-+ dp_disable_link_phy(link, link->public.connector_signal);
-+ }
-+
-+ /* Link Training failed for all Link Settings
-+ * (Lane Count is still unknown)
-+ */
-+ if (!success) {
-+ /* If all LT fails for all settings,
-+ * set verified = failed safe (1 lane low)
-+ */
-+ link->verified_link_cap.lane_count = LANE_COUNT_ONE;
-+ link->verified_link_cap.link_rate = LINK_RATE_LOW;
-+
-+ link->verified_link_cap.link_spread =
-+ LINK_SPREAD_DISABLED;
-+ }
-+
-+ link->max_link_setting = link->verified_link_cap;
-+
-+ return success;
-+}
-+
-+static uint32_t bandwidth_in_kbps_from_timing(
-+ const struct dc_crtc_timing *timing)
-+{
-+ uint32_t bits_per_channel = 0;
-+ uint32_t kbps;
-+ switch (timing->display_color_depth) {
-+
-+ case COLOR_DEPTH_666:
-+ bits_per_channel = 6;
-+ break;
-+ case COLOR_DEPTH_888:
-+ bits_per_channel = 8;
-+ break;
-+ case COLOR_DEPTH_101010:
-+ bits_per_channel = 10;
-+ break;
-+ case COLOR_DEPTH_121212:
-+ bits_per_channel = 12;
-+ break;
-+ case COLOR_DEPTH_141414:
-+ bits_per_channel = 14;
-+ break;
-+ case COLOR_DEPTH_161616:
-+ bits_per_channel = 16;
-+ break;
-+ default:
-+ break;
-+ }
-+ ASSERT(bits_per_channel != 0);
-+
-+ kbps = timing->pix_clk_khz;
-+ kbps *= bits_per_channel;
-+
-+ if (timing->flags.Y_ONLY != 1)
-+ /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/
-+ kbps *= 3;
-+
-+ return kbps;
-+
-+}
-+
-+static uint32_t bandwidth_in_kbps_from_link_settings(
-+ const struct link_settings *link_setting)
-+{
-+ uint32_t link_rate_in_kbps = link_setting->link_rate *
-+ LINK_RATE_REF_FREQ_IN_KHZ;
-+
-+ uint32_t lane_count = link_setting->lane_count;
-+ uint32_t kbps = link_rate_in_kbps;
-+ kbps *= lane_count;
-+ kbps *= 8; /* 8 bits per byte*/
-+
-+ return kbps;
-+
-+}
-+
-+bool dp_validate_mode_timing(
-+ struct core_link *link,
-+ const struct dc_crtc_timing *timing)
-+{
-+ uint32_t req_bw;
-+ uint32_t max_bw;
-+
-+ const struct link_settings *link_setting;
-+
-+ /*always DP fail safe mode*/
-+ if (timing->pix_clk_khz == (uint32_t)25175 &&
-+ timing->h_addressable == (uint32_t)640 &&
-+ timing->v_addressable == (uint32_t)480)
-+ return true;
-+
-+ /* For static validation we always use reported
-+ * link settings for other cases, when no modelist
-+ * changed we can use verified link setting*/
-+ link_setting = &link->reported_link_cap;
-+
-+ /* TODO: DYNAMIC_VALIDATION needs to be implemented */
-+ /*if (flags.DYNAMIC_VALIDATION == 1 &&
-+ link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)
-+ link_setting = &link->verified_link_cap;
-+ */
-+
-+ req_bw = bandwidth_in_kbps_from_timing(timing);
-+ max_bw = bandwidth_in_kbps_from_link_settings(link_setting);
-+
-+ if (req_bw < max_bw) {
-+ /* remember the biggest mode here, during
-+ * initial link training (to get
-+ * verified_link_cap), LS sends event about
-+ * cannot train at reported cap to upper
-+ * layer and upper layer will re-enumerate modes.
-+ * this is not necessary if the lower
-+ * verified_link_cap is enough to drive
-+ * all the modes */
-+
-+ /* TODO: DYNAMIC_VALIDATION needs to be implemented */
-+ /* if (flags.DYNAMIC_VALIDATION == 1)
-+ dpsst->max_req_bw_for_verified_linkcap = dal_max(
-+ dpsst->max_req_bw_for_verified_linkcap, req_bw); */
-+ return true;
-+ } else
-+ return false;
-+}
-+
-+void decide_link_settings(struct core_stream *stream,
-+ struct link_settings *link_setting)
-+{
-+
-+ const struct link_settings *cur_ls;
-+ struct core_link* link;
-+ uint32_t req_bw;
-+ uint32_t link_bw;
-+ uint32_t i;
-+
-+ req_bw = bandwidth_in_kbps_from_timing(
-+ &stream->public.timing);
-+
-+ /* if preferred is specified through AMDDP, use it, if it's enough
-+ * to drive the mode
-+ */
-+ link = stream->sink->link;
-+
-+ if ((link->reported_link_cap.lane_count != LANE_COUNT_UNKNOWN) &&
-+ (link->reported_link_cap.link_rate <=
-+ link->verified_link_cap.link_rate)) {
-+
-+ link_bw = bandwidth_in_kbps_from_link_settings(
-+ &link->reported_link_cap);
-+
-+ if (req_bw < link_bw) {
-+ *link_setting = link->reported_link_cap;
-+ return;
-+ }
-+ }
-+
-+ /* search for first suitable setting for the requested
-+ * bandwidth
-+ */
-+ for (i = 0; i < get_link_training_fallback_table_len(link); i++) {
-+
-+ cur_ls = get_link_training_fallback_table(link, i);
-+
-+ link_bw =
-+ bandwidth_in_kbps_from_link_settings(
-+ cur_ls);
-+
-+ if (req_bw < link_bw) {
-+ if (is_link_setting_supported(
-+ cur_ls,
-+ &link->max_link_setting)) {
-+ *link_setting = *cur_ls;
-+ return;
-+ }
-+ }
-+ }
-+
-+ BREAK_TO_DEBUGGER();
-+ ASSERT(link->verified_link_cap.lane_count !=
-+ LANE_COUNT_UNKNOWN);
-+
-+ *link_setting = link->verified_link_cap;
-+}
-+
-+/*************************Short Pulse IRQ***************************/
-+
-+static bool hpd_rx_irq_check_link_loss_status(
-+ struct core_link *link,
-+ union hpd_irq_data *hpd_irq_dpcd_data)
-+{
-+ uint8_t irq_reg_rx_power_state;
-+ enum dc_status dpcd_result = DC_ERROR_UNEXPECTED;
-+ union lane_status lane_status;
-+ uint32_t lane;
-+ bool sink_status_changed;
-+ bool return_code;
-+
-+ sink_status_changed = false;
-+ return_code = false;
-+
-+ if (link->cur_link_settings.lane_count == 0)
-+ return return_code;
-+ /*1. Check that we can handle interrupt: Not in FS DOS,
-+ * Not in "Display Timeout" state, Link is trained.
-+ */
-+
-+ dpcd_result = core_link_read_dpcd(link,
-+ DPCD_ADDRESS_POWER_STATE,
-+ &irq_reg_rx_power_state,
-+ sizeof(irq_reg_rx_power_state));
-+
-+ if (dpcd_result != DC_OK) {
-+ irq_reg_rx_power_state = DP_PWR_STATE_D0;
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_HPD_IRQ,
-+ "%s: DPCD read failed to obtain power state.\n",
-+ __func__);
-+ }
-+
-+ if (irq_reg_rx_power_state == DP_PWR_STATE_D0) {
-+
-+ /*2. Check that Link Status changed, before re-training.*/
-+
-+ /*parse lane status*/
-+ for (lane = 0; lane <
-+ (uint32_t)(link->cur_link_settings.lane_count) &&
-+ !sink_status_changed; lane++) {
-+
-+ /* check status of lanes 0,1
-+ * changed DpcdAddress_Lane01Status (0x202)*/
-+ lane_status.raw = get_nibble_at_index(
-+ &hpd_irq_dpcd_data->bytes.lane01_status.raw,
-+ lane);
-+
-+ if (!lane_status.bits.CHANNEL_EQ_DONE_0 ||
-+ !lane_status.bits.CR_DONE_0 ||
-+ !lane_status.bits.SYMBOL_LOCKED_0) {
-+ /* if one of the channel equalization, clock
-+ * recovery or symbol lock is dropped
-+ * consider it as (link has been
-+ * dropped) dp sink status has changed*/
-+ sink_status_changed = true;
-+ break;
-+ }
-+
-+ }
-+
-+ /* Check interlane align.*/
-+ if (sink_status_changed ||
-+ !hpd_irq_dpcd_data->bytes.lane_status_updated.bits.
-+ INTERLANE_ALIGN_DONE) {
-+
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_HPD_IRQ,
-+ "%s: Link Status changed.\n",
-+ __func__);
-+
-+ return_code = true;
-+ }
-+ }
-+
-+ return return_code;
-+}
-+
-+static enum dc_status read_hpd_rx_irq_data(
-+ struct core_link *link,
-+ union hpd_irq_data *irq_data)
-+{
-+ /* The HW reads 16 bytes from 200h on HPD,
-+ * but if we get an AUX_DEFER, the HW cannot retry
-+ * and this causes the CTS tests 4.3.2.1 - 3.2.4 to
-+ * fail, so we now explicitly read 6 bytes which is
-+ * the req from the above mentioned test cases.
-+ */
-+ return core_link_read_dpcd(
-+ link,
-+ DPCD_ADDRESS_SINK_COUNT,
-+ irq_data->raw,
-+ sizeof(union hpd_irq_data));
-+}
-+
-+bool dc_link_handle_hpd_rx_irq(const struct dc_link *dc_link)
-+{
-+ struct core_link *link = DC_LINK_TO_LINK(dc_link);
-+ union hpd_irq_data hpd_irq_dpcd_data = {{{{0}}}};
-+ enum dc_status result = DDC_RESULT_UNKNOWN;
-+ bool status = false;
-+ /* For use cases related to down stream connection status change,
-+ * PSR and device auto test, refer to function handle_sst_hpd_irq
-+ * in DAL2.1*/
-+
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_HPD_IRQ,
-+ "%s: Got short pulse HPD on connector %d\n",
-+ __func__, link->connector_index);
-+
-+ /* All the "handle_hpd_irq_xxx()" methods
-+ * should be called only after
-+ * dal_dpsst_ls_read_hpd_irq_data
-+ * Order of calls is important too
-+ */
-+ result = read_hpd_rx_irq_data(link, &hpd_irq_dpcd_data);
-+
-+ if (result != DC_OK) {
-+ dal_logger_write(link->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_HPD_IRQ,
-+ "%s: DPCD read failed to obtain irq data\n",
-+ __func__);
-+ return false;
-+ }
-+
-+ /* check if we have MST msg and return since we poll for it */
-+ if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY ||
-+ hpd_irq_dpcd_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY)
-+ return false;
-+
-+
-+ /* For now we only handle 'Downstream port status' case. */
-+ /* If we got sink count changed it means Downstream port status changed,
-+ * then DM should call DC to do the detection. */
-+ if (hpd_rx_irq_check_link_loss_status(
-+ link,
-+ &hpd_irq_dpcd_data)) {
-+ perform_link_training(link, &link->cur_link_settings, true);
-+ status = false;
-+ }
-+
-+ if (hpd_irq_dpcd_data.bytes.sink_cnt.bits.SINK_COUNT
-+ != link->dpcd_sink_count)
-+ status = true;
-+
-+ /* reasons for HPD RX:
-+ * 1. Link Loss - ie Re-train the Link
-+ * 2. MST sideband message
-+ * 3. Automated Test - ie. Internal Commit
-+ * 4. CP (copy protection) - (not interesting for DM???)
-+ * 5. DRR
-+ * 6. Downstream Port status changed -ie. Detect - this the only one
-+ * which is interesting for DM because it must call dc_link_detect.
-+ */
-+ return status;
-+}
-+
-+/*query dpcd for version and mst cap addresses*/
-+bool is_mst_supported(struct core_link *link)
-+{
-+ bool mst = false;
-+ enum dc_status st = DC_OK;
-+ union dpcd_rev rev;
-+ union mstm_cap cap;
-+
-+ rev.raw = 0;
-+ cap.raw = 0;
-+
-+ st = core_link_read_dpcd(link, DPCD_ADDRESS_DPCD_REV, &rev.raw,
-+ sizeof(rev));
-+
-+ if (st == DC_OK && rev.raw >= DPCD_REV_12) {
-+
-+ st = core_link_read_dpcd(link, DPCD_ADDRESS_MSTM_CAP,
-+ &cap.raw, sizeof(cap));
-+ if (st == DC_OK && cap.bits.MST_CAP == 1)
-+ mst = true;
-+ }
-+ return mst;
-+
-+}
-+
-+static void get_active_converter_info(
-+ uint8_t data, struct core_link *link)
-+{
-+ union dp_downstream_port_present ds_port = { .byte = data };
-+
-+ /* decode converter info*/
-+ if (!ds_port.fields.PORT_PRESENT) {
-+ link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
-+ ddc_service_set_dongle_type(link->ddc,
-+ link->dpcd_caps.dongle_type);
-+ return;
-+ }
-+
-+ switch (ds_port.fields.PORT_TYPE) {
-+ case DOWNSTREAM_VGA:
-+ link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_VGA_CONVERTER;
-+ break;
-+ case DOWNSTREAM_DVI_HDMI:
-+ /* At this point we don't know is it DVI or HDMI,
-+ * assume DVI.*/
-+ link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_DVI_CONVERTER;
-+ break;
-+ default:
-+ link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
-+ break;
-+ }
-+
-+ if (link->dpcd_caps.dpcd_rev.raw >= DCS_DPCD_REV_11) {
-+ uint8_t det_caps[4];
-+ union dwnstream_port_caps_byte0 *port_caps =
-+ (union dwnstream_port_caps_byte0 *)det_caps;
-+ core_link_read_dpcd(link, DPCD_ADDRESS_DWN_STRM_PORT0_CAPS,
-+ det_caps, sizeof(det_caps));
-+
-+ switch (port_caps->bits.DWN_STRM_PORTX_TYPE) {
-+ case DOWN_STREAM_DETAILED_VGA:
-+ link->dpcd_caps.dongle_type =
-+ DISPLAY_DONGLE_DP_VGA_CONVERTER;
-+ break;
-+ case DOWN_STREAM_DETAILED_DVI:
-+ link->dpcd_caps.dongle_type =
-+ DISPLAY_DONGLE_DP_DVI_CONVERTER;
-+ break;
-+ case DOWN_STREAM_DETAILED_HDMI:
-+ link->dpcd_caps.dongle_type =
-+ DISPLAY_DONGLE_DP_HDMI_CONVERTER;
-+
-+ if (ds_port.fields.DETAILED_CAPS) {
-+
-+ union dwnstream_port_caps_byte3_hdmi
-+ hdmi_caps = {.raw = det_caps[3] };
-+
-+ link->dpcd_caps.is_dp_hdmi_s3d_converter =
-+ hdmi_caps.bits.FRAME_SEQ_TO_FRAME_PACK;
-+ }
-+ break;
-+ }
-+ }
-+ ddc_service_set_dongle_type(link->ddc,
-+ link->dpcd_caps.dongle_type);
-+}
-+
-+static void dp_wa_power_up_0010FA(struct core_link *link, uint8_t *dpcd_data,
-+ int length)
-+{
-+ int retry = 0;
-+ struct dp_device_vendor_id dp_id;
-+ union dp_downstream_port_present ds_port = { 0 };
-+
-+ if (!link->dpcd_caps.dpcd_rev.raw) {
-+ do {
-+ dp_receiver_power_ctrl(link, true);
-+ core_link_read_dpcd(link, DPCD_ADDRESS_DPCD_REV,
-+ dpcd_data, length);
-+ link->dpcd_caps.dpcd_rev.raw = dpcd_data[
-+ DPCD_ADDRESS_DPCD_REV -
-+ DPCD_ADDRESS_DPCD_REV];
-+ } while (retry++ < 4 && !link->dpcd_caps.dpcd_rev.raw);
-+ }
-+
-+ ds_port.byte = dpcd_data[DPCD_ADDRESS_DOWNSTREAM_PORT_PRESENT -
-+ DPCD_ADDRESS_DPCD_REV];
-+
-+ get_active_converter_info(ds_port.byte, link);
-+
-+ /* read IEEE branch device id */
-+ core_link_read_dpcd(link, DPCD_ADDRESS_BRANCH_DEVICE_ID_START,
-+ (uint8_t *)&dp_id, sizeof(dp_id));
-+ link->dpcd_caps.branch_dev_id =
-+ (dp_id.ieee_oui[0] << 16) +
-+ (dp_id.ieee_oui[1] << 8) +
-+ dp_id.ieee_oui[2];
-+
-+ if (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER) {
-+ switch (link->dpcd_caps.branch_dev_id) {
-+ /* Some active dongles (DP-VGA, DP-DLDVI converters) power down
-+ * all internal circuits including AUX communication preventing
-+ * reading DPCD table and EDID (spec violation).
-+ * Encoder will skip DP RX power down on disable_output to
-+ * keep receiver powered all the time.*/
-+ case DP_BRANCH_DEVICE_ID_1:
-+ case DP_BRANCH_DEVICE_ID_4:
-+ link->dp_wa.bits.KEEP_RECEIVER_POWERED = 1;
-+ break;
-+
-+ /* TODO: May need work around for other dongles. */
-+ default:
-+ link->dp_wa.bits.KEEP_RECEIVER_POWERED = 0;
-+ break;
-+ }
-+ } else
-+ link->dp_wa.bits.KEEP_RECEIVER_POWERED = 0;
-+}
-+
-+static void retrieve_link_cap(struct core_link *link)
-+{
-+ uint8_t dpcd_data[
-+ DPCD_ADDRESS_EDP_CONFIG_CAP -
-+ DPCD_ADDRESS_DPCD_REV + 1];
-+
-+ union down_stream_port_count down_strm_port_count;
-+ union edp_configuration_cap edp_config_cap;
-+ union max_down_spread max_down_spread;
-+ union dp_downstream_port_present ds_port = { 0 };
-+
-+ dc_service_memset(dpcd_data, '\0', sizeof(dpcd_data));
-+ dc_service_memset(&down_strm_port_count,
-+ '\0', sizeof(union down_stream_port_count));
-+ dc_service_memset(&edp_config_cap, '\0',
-+ sizeof(union edp_configuration_cap));
-+ dc_service_memset(&max_down_spread, '\0',
-+ sizeof(union max_down_spread));
-+
-+ core_link_read_dpcd(link, DPCD_ADDRESS_DPCD_REV,
-+ dpcd_data, sizeof(dpcd_data));
-+ link->dpcd_caps.dpcd_rev.raw = dpcd_data[
-+ DPCD_ADDRESS_DPCD_REV -
-+ DPCD_ADDRESS_DPCD_REV];
-+
-+ ds_port.byte = dpcd_data[DPCD_ADDRESS_DOWNSTREAM_PORT_PRESENT -
-+ DPCD_ADDRESS_DPCD_REV];
-+
-+ get_active_converter_info(ds_port.byte, link);
-+
-+ dp_wa_power_up_0010FA(link, dpcd_data, sizeof(dpcd_data));
-+
-+ link->dpcd_caps.allow_invalid_MSA_timing_param =
-+ down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
-+
-+ link->dpcd_caps.max_ln_count.raw = dpcd_data[
-+ DPCD_ADDRESS_MAX_LANE_COUNT - DPCD_ADDRESS_DPCD_REV];
-+
-+ max_down_spread.raw = dpcd_data[
-+ DPCD_ADDRESS_MAX_DOWNSPREAD - DPCD_ADDRESS_DPCD_REV];
-+
-+ link->reported_link_cap.lane_count =
-+ link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
-+ link->reported_link_cap.link_rate = dpcd_data[
-+ DPCD_ADDRESS_MAX_LINK_RATE - DPCD_ADDRESS_DPCD_REV];
-+ link->reported_link_cap.link_spread =
-+ max_down_spread.bits.MAX_DOWN_SPREAD ?
-+ LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
-+
-+ edp_config_cap.raw = dpcd_data[
-+ DPCD_ADDRESS_EDP_CONFIG_CAP - DPCD_ADDRESS_DPCD_REV];
-+ link->dpcd_caps.panel_mode_edp =
-+ edp_config_cap.bits.ALT_SCRAMBLER_RESET;
-+
-+ link->edp_revision = DPCD_EDP_REVISION_EDP_UNKNOWN;
-+
-+ /* read sink count */
-+ core_link_read_dpcd(link,
-+ DPCD_ADDRESS_SINK_COUNT,
-+ &link->dpcd_caps.sink_count.raw,
-+ sizeof(link->dpcd_caps.sink_count.raw));
-+
-+ /* Display control registers starting at DPCD 700h are only valid and
-+ * enabled if this eDP config cap bit is set. */
-+ if (edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE) {
-+ /* Read the Panel's eDP revision at DPCD 700h. */
-+ core_link_read_dpcd(link,
-+ DPCD_ADDRESS_EDP_REV,
-+ (uint8_t *)(&link->edp_revision),
-+ sizeof(link->edp_revision));
-+ }
-+ /* TODO: Confirm if need retrieve_psr_link_cap */
-+}
-+
-+void detect_dp_sink_caps(struct core_link *link)
-+{
-+ retrieve_link_cap(link);
-+
-+ /* dc init_hw has power encoder using default
-+ * signal for connector. For native DP, no
-+ * need to power up encoder again. If not native
-+ * DP, hw_init may need check signal or power up
-+ * encoder here.
-+ */
-+
-+ if (is_mst_supported(link)) {
-+ link->verified_link_cap = link->reported_link_cap;
-+ } else {
-+ dp_hbr_verify_link_cap(link,
-+ &link->reported_link_cap);
-+ }
-+ /* TODO save sink caps in link->sink */
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c
-new file mode 100644
-index 0000000..164cdeb
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_link_hwss.c
-@@ -0,0 +1,188 @@
-+/* Copyright 2015 Advanced Micro Devices, Inc. */
-+
-+#include "dc_services.h"
-+#include "dc.h"
-+#include "inc/core_dc.h"
-+#include "include/ddc_service_types.h"
-+#include "include/i2caux_interface.h"
-+#include "link_hwss.h"
-+#include "include/connector_interface.h"
-+#include "hw_sequencer.h"
-+#include "include/ddc_service_interface.h"
-+
-+enum dc_status core_link_read_dpcd(
-+ struct core_link* link,
-+ uint32_t address,
-+ uint8_t *data,
-+ uint32_t size)
-+{
-+ if (dal_ddc_service_read_dpcd_data(link->ddc, address, data, size)
-+ != DDC_RESULT_SUCESSFULL)
-+ return DC_ERROR_UNEXPECTED;
-+
-+ return DC_OK;
-+}
-+
-+enum dc_status core_link_write_dpcd(
-+ struct core_link* link,
-+ uint32_t address,
-+ const uint8_t *data,
-+ uint32_t size)
-+{
-+ if (dal_ddc_service_write_dpcd_data(link->ddc, address, data, size)
-+ != DDC_RESULT_SUCESSFULL)
-+ return DC_ERROR_UNEXPECTED;
-+
-+ return DC_OK;
-+}
-+
-+void dp_receiver_power_ctrl(struct core_link *link, bool on)
-+{
-+ uint8_t state;
-+
-+ state = on ? DP_POWER_STATE_D0 : DP_POWER_STATE_D3;
-+
-+ core_link_write_dpcd(link, DPCD_ADDRESS_POWER_STATE, &state,
-+ sizeof(state));
-+}
-+
-+
-+/* TODO: HBR2 need raise clock for DP link training */
-+enum dc_status dp_enable_link_phy(
-+ struct core_link *link,
-+ enum signal_type signal,
-+ enum engine_id engine,
-+ const struct link_settings *link_settings)
-+{
-+ enum dc_status status = DC_OK;
-+
-+ if (link->dc->hwss.encoder_enable_output(
-+ link->link_enc,
-+ link_settings,
-+ engine,
-+ CLOCK_SOURCE_ID_EXTERNAL,
-+ signal,
-+ COLOR_DEPTH_UNDEFINED,
-+ 0) != ENCODER_RESULT_OK)
-+ status = DC_ERROR_UNEXPECTED;
-+
-+ dp_receiver_power_ctrl(link, true);
-+
-+ return status;
-+}
-+
-+void dp_disable_link_phy(struct core_link *link, enum signal_type signal)
-+{
-+ if(!link)
-+ return;
-+
-+ if (!link->dp_wa.bits.KEEP_RECEIVER_POWERED)
-+ dp_receiver_power_ctrl(link, false);
-+
-+ link->dc->hwss.encoder_disable_output(link->link_enc, signal);
-+
-+ /* Clear current link setting.*/
-+ dc_service_memset(&link->cur_link_settings, 0,
-+ sizeof(link->cur_link_settings));
-+}
-+
-+bool dp_set_hw_training_pattern(
-+ struct core_link *link,
-+ enum hw_dp_training_pattern pattern)
-+{
-+ enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
-+ struct encoder_set_dp_phy_pattern_param pattern_param = {0};
-+ struct link_encoder *encoder = link->link_enc;
-+
-+ switch (pattern) {
-+ case HW_DP_TRAINING_PATTERN_1:
-+ test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN1;
-+ break;
-+ case HW_DP_TRAINING_PATTERN_2:
-+ test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN2;
-+ break;
-+ case HW_DP_TRAINING_PATTERN_3:
-+ test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN3;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ pattern_param.dp_phy_pattern = test_pattern;
-+ pattern_param.custom_pattern = NULL;
-+ pattern_param.custom_pattern_size = 0;
-+ pattern_param.dp_panel_mode = dp_get_panel_mode(link);
-+
-+ link->ctx->dc->hwss.encoder_set_dp_phy_pattern(encoder, &pattern_param);
-+
-+ return true;
-+}
-+
-+
-+bool dp_set_hw_lane_settings(
-+ struct core_link *link,
-+ const struct link_training_settings *link_settings)
-+{
-+ struct link_encoder *encoder = link->link_enc;
-+
-+ /* call Encoder to set lane settings */
-+ link->ctx->dc->hwss.encoder_dp_set_lane_settings(encoder, link_settings);
-+
-+ return true;
-+}
-+
-+enum dp_panel_mode dp_get_panel_mode(struct core_link *link)
-+{
-+ /* We need to explicitly check that connector
-+ * is not DP. Some Travis_VGA get reported
-+ * by video bios as DP.
-+ */
-+ if (link->public.connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
-+
-+ switch (link->dpcd_caps.branch_dev_id) {
-+ case DP_BRANCH_DEVICE_ID_2:
-+ if (strncmp(
-+ link->dpcd_caps.branch_dev_name,
-+ DP_VGA_LVDS_CONVERTER_ID_2,
-+ sizeof(
-+ link->dpcd_caps.
-+ branch_dev_name)) == 0) {
-+ return DP_PANEL_MODE_SPECIAL;
-+ }
-+ break;
-+ case DP_BRANCH_DEVICE_ID_3:
-+ if (strncmp(link->dpcd_caps.branch_dev_name,
-+ DP_VGA_LVDS_CONVERTER_ID_3,
-+ sizeof(
-+ link->dpcd_caps.
-+ branch_dev_name)) == 0) {
-+ return DP_PANEL_MODE_SPECIAL;
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (link->dpcd_caps.panel_mode_edp) {
-+ return DP_PANEL_MODE_EDP;
-+ }
-+ }
-+
-+ return DP_PANEL_MODE_DEFAULT;
-+}
-+
-+void dp_set_hw_test_pattern(
-+ struct core_link *link,
-+ enum dp_test_pattern test_pattern)
-+{
-+ struct encoder_set_dp_phy_pattern_param pattern_param = {0};
-+ struct link_encoder *encoder = link->link_enc;
-+
-+ pattern_param.dp_phy_pattern = test_pattern;
-+ pattern_param.custom_pattern = NULL;
-+ pattern_param.custom_pattern_size = 0;
-+ pattern_param.dp_panel_mode = dp_get_panel_mode(link);
-+
-+ link->ctx->dc->hwss.encoder_set_dp_phy_pattern(encoder, &pattern_param);
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c b/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c
-new file mode 100644
-index 0000000..5803e22
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c
-@@ -0,0 +1,378 @@
-+/*
-+* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#include "dc_services.h"
-+
-+#include "resource.h"
-+#include "include/irq_service_interface.h"
-+#include "link_encoder_types.h"
-+#include "stream_encoder_types.h"
-+
-+
-+void unreference_clock_source(
-+ struct resource_context *res_ctx,
-+ struct clock_source *clock_source)
-+{
-+ int i;
-+ for (i = 0; i < res_ctx->pool.clk_src_count; i++) {
-+ if (res_ctx->pool.clock_sources[i] == clock_source) {
-+ res_ctx->clock_source_ref_count[i]--;
-+ }
-+ }
-+}
-+
-+void reference_clock_source(
-+ struct resource_context *res_ctx,
-+ struct clock_source *clock_source)
-+{
-+ int i;
-+ for (i = 0; i < res_ctx->pool.clk_src_count; i++) {
-+ if (res_ctx->pool.clock_sources[i] == clock_source) {
-+ res_ctx->clock_source_ref_count[i]++;
-+ }
-+ }
-+}
-+
-+bool is_same_timing(
-+ const struct dc_crtc_timing *timing1,
-+ const struct dc_crtc_timing *timing2)
-+{
-+ return dal_memcmp(timing1, timing2, sizeof(struct dc_crtc_timing)) == 0;
-+}
-+
-+static bool is_sharable_clk_src(
-+ const struct core_stream *stream_with_clk_src,
-+ const struct core_stream *stream)
-+{
-+ enum clock_source_id id = dal_clock_source_get_id(
-+ stream_with_clk_src->clock_source);
-+
-+ if (stream_with_clk_src->clock_source == NULL)
-+ return false;
-+
-+ if (!dc_is_dp_signal(stream->signal) && id == CLOCK_SOURCE_ID_EXTERNAL)
-+ return false;
-+
-+ if(!is_same_timing(
-+ &stream_with_clk_src->public.timing, &stream->public.timing))
-+ return false;
-+
-+ return true;
-+}
-+
-+struct clock_source *find_used_clk_src_for_sharing(
-+ struct validate_context *context,
-+ struct core_stream *stream)
-+{
-+ uint8_t i, j;
-+ for (i = 0; i < context->target_count; i++) {
-+ struct core_target *target = context->targets[i];
-+ for (j = 0; j < target->stream_count; j++)
-+ {
-+ if (target->streams[j]->clock_source == NULL)
-+ continue;
-+ if (is_sharable_clk_src(target->streams[j], stream))
-+ return target->streams[j]->clock_source;
-+ }
-+ }
-+
-+ return NULL;
-+}
-+
-+static enum pixel_format convert_pixel_format_to_dalsurface(
-+ enum surface_pixel_format surface_pixel_format)
-+{
-+ enum pixel_format dal_pixel_format = PIXEL_FORMAT_UNKNOWN;
-+
-+ switch (surface_pixel_format) {
-+ case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
-+ dal_pixel_format = PIXEL_FORMAT_INDEX8;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
-+ dal_pixel_format = PIXEL_FORMAT_RGB565;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
-+ dal_pixel_format = PIXEL_FORMAT_RGB565;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
-+ dal_pixel_format = PIXEL_FORMAT_ARGB8888;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
-+ dal_pixel_format = PIXEL_FORMAT_ARGB8888;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
-+ dal_pixel_format = PIXEL_FORMAT_ARGB2101010;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
-+ dal_pixel_format = PIXEL_FORMAT_ARGB2101010;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
-+ dal_pixel_format = PIXEL_FORMAT_ARGB2101010_XRBIAS;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
-+ dal_pixel_format = PIXEL_FORMAT_FP16;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
-+ dal_pixel_format = PIXEL_FORMAT_FP16;
-+ break;
-+
-+
-+ case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
-+ dal_pixel_format = PIXEL_FORMAT_420BPP12;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
-+ dal_pixel_format = PIXEL_FORMAT_420BPP12;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_VIDEO_422_YCb:
-+ dal_pixel_format = PIXEL_FORMAT_422BPP16;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_VIDEO_422_YCr:
-+ dal_pixel_format = PIXEL_FORMAT_422BPP16;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_VIDEO_422_CbY:
-+ dal_pixel_format = PIXEL_FORMAT_422BPP16;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_VIDEO_422_CrY:
-+ dal_pixel_format = PIXEL_FORMAT_422BPP16;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_VIDEO_444_ACrYCb1555:
-+ dal_pixel_format = PIXEL_FORMAT_444BPP16;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_VIDEO_444_CrYCb565:
-+ dal_pixel_format = PIXEL_FORMAT_444BPP16;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_VIDEO_444_ACrYCb4444:
-+ dal_pixel_format = PIXEL_FORMAT_444BPP16;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_VIDEO_444_CbYCrA5551:
-+ dal_pixel_format = PIXEL_FORMAT_444BPP16;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_VIDEO_444_ACrYCb8888:
-+ dal_pixel_format = PIXEL_FORMAT_444BPP32;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_VIDEO_444_ACrYCb2101010:
-+ dal_pixel_format = PIXEL_FORMAT_444BPP32;
-+ break;
-+ case SURFACE_PIXEL_FORMAT_VIDEO_444_CbYCrA1010102:
-+ dal_pixel_format = PIXEL_FORMAT_444BPP32;
-+ break;
-+ default:
-+ dal_pixel_format = PIXEL_FORMAT_UNKNOWN;
-+ break;
-+ }
-+ return dal_pixel_format;
-+}
-+
-+static void calculate_viewport(
-+ const struct dc_surface *surface,
-+ struct core_stream *stream)
-+{
-+ const struct rect src = surface->src_rect;
-+ const struct rect clip = surface->clip_rect;
-+ const struct rect dst = surface->dst_rect;
-+
-+ /* offset = src.ofs + (clip.ofs - dst.ofs) * scl_ratio
-+ * num_pixels = clip.num_pix * scl_ratio
-+ */
-+ stream->viewport.x = src.x + (clip.x - dst.x) * src.width / dst.width;
-+ stream->viewport.width = clip.width * src.width / dst.width;
-+
-+ stream->viewport.y = src.y + (clip.y - dst.y) * src.height / dst.height;
-+ stream->viewport.height = clip.height * src.height / dst.height;
-+
-+ /* Minimum viewport such that 420/422 chroma vp is non 0 */
-+ if (stream->viewport.width < 2)
-+ {
-+ stream->viewport.width = 2;
-+ }
-+ if (stream->viewport.height < 2)
-+ {
-+ stream->viewport.height = 2;
-+ }
-+}
-+
-+static void calculate_overscan(
-+ const struct dc_surface *surface,
-+ struct core_stream *stream)
-+{
-+ stream->overscan.left = stream->public.dst.x;
-+ if (stream->public.src.x < surface->clip_rect.x)
-+ stream->overscan.left += (surface->clip_rect.x
-+ - stream->public.src.x) * stream->public.dst.width
-+ / stream->public.src.width;
-+
-+ stream->overscan.right = stream->public.timing.h_addressable
-+ - stream->public.dst.x - stream->public.dst.width;
-+ if (stream->public.src.x + stream->public.src.width
-+ > surface->clip_rect.x + surface->clip_rect.width)
-+ stream->overscan.right = stream->public.timing.h_addressable -
-+ dal_fixed31_32_floor(dal_fixed31_32_div(
-+ dal_fixed31_32_from_int(
-+ stream->viewport.width),
-+ stream->ratios.horz)) -
-+ stream->overscan.left;
-+
-+
-+ stream->overscan.top = stream->public.dst.y;
-+ if (stream->public.src.y < surface->clip_rect.y)
-+ stream->overscan.top += (surface->clip_rect.y
-+ - stream->public.src.y) * stream->public.dst.height
-+ / stream->public.src.height;
-+
-+ stream->overscan.bottom = stream->public.timing.v_addressable
-+ - stream->public.dst.y - stream->public.dst.height;
-+ if (stream->public.src.y + stream->public.src.height
-+ > surface->clip_rect.y + surface->clip_rect.height)
-+ stream->overscan.bottom = stream->public.timing.v_addressable -
-+ dal_fixed31_32_floor(dal_fixed31_32_div(
-+ dal_fixed31_32_from_int(
-+ stream->viewport.height),
-+ stream->ratios.vert)) -
-+ stream->overscan.top;
-+
-+
-+ /* TODO: Add timing overscan to finalize overscan calculation*/
-+}
-+
-+static void calculate_scaling_ratios(
-+ const struct dc_surface *surface,
-+ struct core_stream *stream)
-+{
-+ const uint32_t in_w = stream->public.src.width;
-+ const uint32_t in_h = stream->public.src.height;
-+ const uint32_t out_w = stream->public.dst.width;
-+ const uint32_t out_h = stream->public.dst.height;
-+
-+ stream->ratios.horz = dal_fixed31_32_from_fraction(
-+ surface->src_rect.width,
-+ surface->dst_rect.width);
-+ stream->ratios.vert = dal_fixed31_32_from_fraction(
-+ surface->src_rect.height,
-+ surface->dst_rect.height);
-+
-+ if (surface->stereo_format == PLANE_STEREO_FORMAT_SIDE_BY_SIDE)
-+ stream->ratios.horz.value *= 2;
-+ else if (surface->stereo_format
-+ == PLANE_STEREO_FORMAT_TOP_AND_BOTTOM)
-+ stream->ratios.vert.value *= 2;
-+
-+ stream->ratios.vert.value = stream->ratios.vert.value * in_h / out_h;
-+ stream->ratios.horz.value = stream->ratios.horz.value * in_w / out_w;
-+
-+ stream->ratios.horz_c = stream->ratios.horz;
-+ stream->ratios.vert_c = stream->ratios.vert;
-+
-+ if (stream->format == PIXEL_FORMAT_420BPP12) {
-+ stream->ratios.horz_c.value /= 2;
-+ stream->ratios.vert_c.value /= 2;
-+ } else if (stream->format == PIXEL_FORMAT_422BPP16) {
-+ stream->ratios.horz_c.value /= 2;
-+ }
-+}
-+
-+/*TODO: per pipe not per stream*/
-+void build_scaling_params(
-+ const struct dc_surface *surface,
-+ struct core_stream *stream)
-+{
-+ /* Important: scaling ratio calculation requires pixel format,
-+ * overscan calculation requires scaling ratios and viewport
-+ * and lb depth/taps calculation requires overscan. Call sequence
-+ * is therefore important */
-+ stream->format = convert_pixel_format_to_dalsurface(surface->format);
-+
-+ calculate_viewport(surface, stream);
-+
-+ calculate_scaling_ratios(surface, stream);
-+
-+ calculate_overscan(surface, stream);
-+
-+ /* Check if scaling is required update taps if not */
-+ if (dal_fixed31_32_u2d19(stream->ratios.horz) == 1 << 19)
-+ stream->taps.h_taps = 1;
-+ else
-+ stream->taps.h_taps = surface->scaling_quality.h_taps;
-+
-+ if (dal_fixed31_32_u2d19(stream->ratios.horz_c) == 1 << 19)
-+ stream->taps.h_taps_c = 1;
-+ else
-+ stream->taps.h_taps_c = surface->scaling_quality.h_taps_c;
-+
-+ if (dal_fixed31_32_u2d19(stream->ratios.vert) == 1 << 19)
-+ stream->taps.v_taps = 1;
-+ else
-+ stream->taps.v_taps = surface->scaling_quality.v_taps;
-+
-+ if (dal_fixed31_32_u2d19(stream->ratios.vert_c) == 1 << 19)
-+ stream->taps.v_taps_c = 1;
-+ else
-+ stream->taps.v_taps_c = surface->scaling_quality.v_taps_c;
-+}
-+
-+void build_scaling_params_for_context(
-+ const struct dc *dc,
-+ struct validate_context *context)
-+{
-+ uint8_t i, j, k;
-+ for (i = 0; i < context->target_count; i++) {
-+ struct core_target *target = context->targets[i];
-+ if (context->target_flags[i].unchanged)
-+ continue;
-+ for (j = 0; j < target->status.surface_count; j++) {
-+ const struct dc_surface *surface = target->status.surfaces[j];
-+ for (k = 0; k < target->stream_count; k++) {
-+ struct core_stream *stream = target->streams[k];
-+
-+ build_scaling_params(surface, stream);
-+ }
-+ }
-+ }
-+}
-+
-+bool logical_attach_surfaces_to_target(
-+ struct dc_surface *surfaces[],
-+ uint8_t surface_count,
-+ struct dc_target *dc_target)
-+{
-+ uint8_t i;
-+ struct core_target *target = DC_TARGET_TO_CORE(dc_target);
-+
-+ if (target->status.surface_count >= MAX_SURFACE_NUM) {
-+ dal_error("Surface: this target has too many surfaces!\n");
-+ return false;
-+ }
-+
-+ for (i = 0; i < target->status.surface_count; i++)
-+ dc_surface_release(target->status.surfaces[i]);
-+
-+ for (i = 0; i < surface_count; i++) {
-+ struct core_surface *surface = DC_SURFACE_TO_CORE(surfaces[i]);
-+ surface->status.dc_target = &target->public;
-+ target->status.surfaces[i] = surfaces[i];
-+ dc_surface_retain(target->status.surfaces[i]);
-+ }
-+ target->status.surface_count = surface_count;
-+
-+ return true;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_sink.c b/drivers/gpu/drm/amd/dal/dc/core/dc_sink.c
-new file mode 100644
-index 0000000..3d537d5
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_sink.c
-@@ -0,0 +1,118 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dc_services.h"
-+#include "dc_helpers.h"
-+#include "core_types.h"
-+
-+/*******************************************************************************
-+ * Private definitions
-+ ******************************************************************************/
-+
-+struct sink {
-+ struct core_sink protected;
-+ int ref_count;
-+};
-+
-+#define DC_SINK_TO_SINK(dc_sink) \
-+ container_of(dc_sink, struct sink, protected.public)
-+
-+/*******************************************************************************
-+ * Private functions
-+ ******************************************************************************/
-+
-+static void destruct(struct sink *sink)
-+{
-+
-+}
-+
-+static bool construct(struct sink *sink, const struct sink_init_data *init_params)
-+{
-+
-+ struct core_link *core_link = DC_LINK_TO_LINK(init_params->link);
-+
-+ sink->protected.public.sink_signal = init_params->sink_signal;
-+ sink->protected.link = core_link;
-+ sink->protected.ctx = core_link->ctx;
-+ sink->protected.dongle_max_pix_clk = init_params->dongle_max_pix_clk;
-+ sink->protected.converter_disable_audio =
-+ init_params->converter_disable_audio;
-+
-+ return true;
-+}
-+
-+/*******************************************************************************
-+ * Public functions
-+ ******************************************************************************/
-+
-+void dc_sink_retain(const struct dc_sink *dc_sink)
-+{
-+ struct sink *sink = DC_SINK_TO_SINK(dc_sink);
-+
-+ ++sink->ref_count;
-+}
-+
-+void dc_sink_release(const struct dc_sink *dc_sink)
-+{
-+ struct core_sink *core_sink = DC_SINK_TO_CORE(dc_sink);
-+ struct sink *sink = DC_SINK_TO_SINK(dc_sink);
-+
-+ --sink->ref_count;
-+
-+ if (sink->ref_count == 0) {
-+ destruct(sink);
-+ dc_service_free(core_sink->ctx, sink);
-+ }
-+}
-+
-+
-+/*******************************************************************************
-+ * Protected functions - visible only inside of DC (not visible in DM)
-+ ******************************************************************************/
-+
-+struct dc_sink *sink_create(const struct sink_init_data *init_params)
-+{
-+ struct core_link *core_link = DC_LINK_TO_LINK(init_params->link);
-+
-+ struct sink *sink = dc_service_alloc(core_link->ctx, sizeof(*sink));
-+
-+ if (NULL == sink)
-+ goto alloc_fail;
-+
-+ if (false == construct(sink, init_params))
-+ goto construct_fail;
-+
-+ /* TODO should we move this outside to where the assignment actually happens? */
-+ dc_sink_retain(&sink->protected.public);
-+
-+ return &sink->protected.public;
-+
-+construct_fail:
-+ dc_service_free(core_link->ctx, sink);
-+
-+alloc_fail:
-+ return NULL;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_stream.c b/drivers/gpu/drm/amd/dal/dc/core/dc_stream.c
-new file mode 100644
-index 0000000..1a7bf50
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_stream.c
-@@ -0,0 +1,172 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#include "dc_services.h"
-+#include "dc.h"
-+#include "core_types.h"
-+#include "resource.h"
-+
-+/*******************************************************************************
-+ * Private definitions
-+ ******************************************************************************/
-+
-+struct stream {
-+ struct core_stream protected;
-+ int ref_count;
-+};
-+
-+#define DC_STREAM_TO_STREAM(dc_stream) container_of(dc_stream, struct stream, protected.public)
-+
-+/*******************************************************************************
-+ * Private functions
-+ ******************************************************************************/
-+
-+static void build_bit_depth_reduction_params(
-+ struct bit_depth_reduction_params *fmt_bit_depth)
-+{
-+ /*TODO: Need to un-hardcode, refer to function with same name
-+ * in dal2 hw_sequencer*/
-+
-+ fmt_bit_depth->flags.TRUNCATE_ENABLED = 0;
-+ fmt_bit_depth->flags.SPATIAL_DITHER_ENABLED = 0;
-+ fmt_bit_depth->flags.FRAME_MODULATION_ENABLED = 0;
-+ fmt_bit_depth->flags.SPATIAL_DITHER_DEPTH = 1;
-+
-+ fmt_bit_depth->flags.SPATIAL_DITHER_ENABLED = 1;
-+ /* frame random is on by default */
-+ fmt_bit_depth->flags.FRAME_RANDOM = 1;
-+ /* apply RGB dithering */
-+ fmt_bit_depth->flags.RGB_RANDOM = true;
-+
-+ return;
-+
-+}
-+
-+static void setup_pixel_encoding(
-+ struct clamping_and_pixel_encoding_params *clamping)
-+{
-+ /*TODO: Need to un-hardcode, refer to function with same name
-+ * in dal2 hw_sequencer*/
-+
-+ clamping->pixel_encoding = PIXEL_ENCODING_RGB;
-+
-+ return;
-+}
-+
-+static bool construct(struct core_stream *stream,
-+ const struct dc_sink *dc_sink_data)
-+{
-+ uint32_t i = 0;
-+
-+ stream->sink = DC_SINK_TO_CORE(dc_sink_data);
-+ stream->ctx = stream->sink->ctx;
-+ stream->public.sink = dc_sink_data;
-+
-+ dc_sink_retain(dc_sink_data);
-+
-+ build_bit_depth_reduction_params(&stream->fmt_bit_depth);
-+ setup_pixel_encoding(&stream->clamping);
-+
-+ /* Copy audio modes */
-+ /* TODO - Remove this translation */
-+ for (i = 0; i < (dc_sink_data->edid_caps.audio_mode_count); i++)
-+ {
-+ stream->public.audio_info.modes[i].channel_count = dc_sink_data->edid_caps.audio_modes[i].channel_count;
-+ stream->public.audio_info.modes[i].format_code = dc_sink_data->edid_caps.audio_modes[i].format_code;
-+ stream->public.audio_info.modes[i].sample_rates.all = dc_sink_data->edid_caps.audio_modes[i].sample_rate;
-+ stream->public.audio_info.modes[i].sample_size = dc_sink_data->edid_caps.audio_modes[i].sample_size;
-+ }
-+ stream->public.audio_info.mode_count = dc_sink_data->edid_caps.audio_mode_count;
-+ stream->public.audio_info.audio_latency = dc_sink_data->edid_caps.audio_latency;
-+ stream->public.audio_info.video_latency = dc_sink_data->edid_caps.video_latency;
-+ dc_service_memmove(
-+ stream->public.audio_info.display_name,
-+ dc_sink_data->edid_caps.display_name,
-+ AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS);
-+ stream->public.audio_info.manufacture_id = dc_sink_data->edid_caps.manufacturer_id;
-+ stream->public.audio_info.product_id = dc_sink_data->edid_caps.product_id;
-+ stream->public.audio_info.flags.all = dc_sink_data->edid_caps.speaker_flags;
-+
-+ /* TODO - Unhardcode port_id */
-+ stream->public.audio_info.port_id[0] = 0x5558859e;
-+ stream->public.audio_info.port_id[1] = 0xd989449;
-+
-+ /* EDID CAP translation for HDMI 2.0 */
-+ stream->public.timing.flags.LTE_340MCSC_SCRAMBLE = dc_sink_data->edid_caps.lte_340mcsc_scramble;
-+ return true;
-+}
-+
-+static void destruct(struct core_stream *stream)
-+{
-+ dc_sink_release(&stream->sink->public);
-+}
-+
-+void dc_stream_retain(struct dc_stream *dc_stream)
-+{
-+ struct stream *stream = DC_STREAM_TO_STREAM(dc_stream);
-+ stream->ref_count++;
-+}
-+
-+void dc_stream_release(struct dc_stream *public)
-+{
-+ struct stream *stream = DC_STREAM_TO_STREAM(public);
-+ struct core_stream *protected = DC_STREAM_TO_CORE(public);
-+ struct dc_context *ctx = protected->ctx;
-+ stream->ref_count--;
-+
-+ if (stream->ref_count == 0) {
-+ destruct(protected);
-+ dc_service_free(ctx, stream);
-+ }
-+}
-+
-+struct dc_stream *dc_create_stream_for_sink(const struct dc_sink *dc_sink)
-+{
-+ struct core_sink *sink = DC_SINK_TO_CORE(dc_sink);
-+ struct stream *stream;
-+
-+ if (sink == NULL)
-+ goto alloc_fail;
-+
-+ stream = dc_service_alloc(sink->ctx, sizeof(struct stream));
-+
-+ if (NULL == stream)
-+ goto alloc_fail;
-+
-+ if (false == construct(&stream->protected, dc_sink))
-+ goto construct_fail;
-+
-+ dc_stream_retain(&stream->protected.public);
-+
-+ return &stream->protected.public;
-+
-+construct_fail:
-+ dc_service_free(sink->ctx, stream);
-+
-+alloc_fail:
-+ return NULL;
-+}
-+
-+
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_surface.c b/drivers/gpu/drm/amd/dal/dc/core/dc_surface.c
-new file mode 100644
-index 0000000..41a5feb
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_surface.c
-@@ -0,0 +1,124 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+/* DC interface (public) */
-+#include "dc_services.h"
-+#include "dc.h"
-+
-+/* DC core (private) */
-+#include "core_dc.h"
-+#include "adjustment_types.h"
-+
-+
-+/*******************************************************************************
-+ * Private structures
-+ ******************************************************************************/
-+struct surface {
-+ struct core_surface protected;
-+ enum dc_irq_source irq_source;
-+ int ref_count;
-+};
-+
-+#define DC_SURFACE_TO_SURFACE(dc_surface) container_of(dc_surface, struct surface, protected.public)
-+#define CORE_SURFACE_TO_SURFACE(core_surface) container_of(core_surface, struct surface, protected)
-+
-+/*******************************************************************************
-+ * Private functions
-+ ******************************************************************************/
-+static bool construct(struct dc_context *ctx, struct surface *surface)
-+{
-+ uint32_t i;
-+ struct gamma_ramp *gamma =
-+ &surface->protected.public.gamma_correction;
-+
-+ /* construct gamma default value. */
-+ for (i = 0; i < NUM_OF_RAW_GAMMA_RAMP_RGB_256; i++) {
-+ gamma->gamma_ramp_rgb256x3x16.red[i] =
-+ (unsigned short) (i << 8);
-+ gamma->gamma_ramp_rgb256x3x16.green[i] =
-+ (unsigned short) (i << 8);
-+ gamma->gamma_ramp_rgb256x3x16.blue[i] =
-+ (unsigned short) (i << 8);
-+ }
-+ gamma->type = GAMMA_RAMP_TYPE_RGB256;
-+ gamma->size = sizeof(gamma->gamma_ramp_rgb256x3x16);
-+
-+ surface->protected.ctx = ctx;
-+ return true;
-+}
-+
-+static void destruct(struct surface *surface)
-+{
-+}
-+
-+/*******************************************************************************
-+ * Public functions
-+ ******************************************************************************/
-+void enable_surface_flip_reporting(struct dc_surface *dc_surface,
-+ uint32_t controller_id)
-+{
-+ struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface);
-+ surface->irq_source = controller_id + DC_IRQ_SOURCE_PFLIP1 - 1;
-+ /*register_flip_interrupt(surface);*/
-+}
-+
-+struct dc_surface *dc_create_surface(const struct dc *dc)
-+{
-+ struct surface *surface = dc_service_alloc(dc->ctx, sizeof(*surface));
-+
-+ if (NULL == surface)
-+ goto alloc_fail;
-+
-+ if (false == construct(dc->ctx, surface))
-+ goto construct_fail;
-+
-+ dc_surface_retain(&surface->protected.public);
-+
-+ return &surface->protected.public;
-+
-+construct_fail:
-+ dc_service_free(dc->ctx, surface);
-+
-+alloc_fail:
-+ return NULL;
-+}
-+
-+void dc_surface_retain(const struct dc_surface *dc_surface)
-+{
-+ struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface);
-+
-+ ++surface->ref_count;
-+}
-+
-+void dc_surface_release(const struct dc_surface *dc_surface)
-+{
-+ struct surface *surface = DC_SURFACE_TO_SURFACE(dc_surface);
-+ --surface->ref_count;
-+
-+ if (surface->ref_count == 0) {
-+ destruct(surface);
-+ dc_service_free(surface->protected.ctx, surface);
-+ }
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_target.c b/drivers/gpu/drm/amd/dal/dc/core/dc_target.c
-new file mode 100644
-index 0000000..9243c01
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_target.c
-@@ -0,0 +1,473 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#include "dc_services.h"
-+#include "core_types.h"
-+#include "hw_sequencer.h"
-+#include "resource.h"
-+
-+#define COEFF_RANGE 3
-+#define REGAMMA_COEFF_A0 31308
-+#define REGAMMA_COEFF_A1 12920
-+#define REGAMMA_COEFF_A2 55
-+#define REGAMMA_COEFF_A3 55
-+#define REGAMMA_COEFF_GAMMA 2400
-+
-+struct target {
-+ struct core_target protected;
-+ int ref_count;
-+};
-+
-+#define DC_TARGET_TO_TARGET(dc_target) \
-+ container_of(dc_target, struct target, protected.public)
-+#define CORE_TARGET_TO_TARGET(core_target) \
-+ container_of(core_target, struct target, protected)
-+
-+static void construct(
-+ struct core_target *target,
-+ struct dc_context *ctx,
-+ struct dc_stream *dc_streams[],
-+ uint8_t stream_count)
-+{
-+ uint8_t i;
-+ for (i = 0; i < stream_count; i++) {
-+ target->streams[i] = DC_STREAM_TO_CORE(dc_streams[i]);
-+ target->public.streams[i] = dc_streams[i];
-+ dc_stream_retain(dc_streams[i]);
-+ }
-+
-+ target->ctx = ctx;
-+ target->stream_count = stream_count;
-+}
-+
-+static void destruct(struct core_target *core_target)
-+{
-+ int i;
-+
-+ for (i = 0; i < core_target->status.surface_count; i++) {
-+ dc_surface_release(core_target->status.surfaces[i]);
-+ core_target->status.surfaces[i] = 0;
-+ }
-+ for (i = 0; i < core_target->stream_count; i++) {
-+ dc_stream_release(&core_target->streams[i]->public);
-+ core_target->streams[i] = 0;
-+ }
-+}
-+
-+void dc_target_retain(struct dc_target *dc_target)
-+{
-+ struct target *target = DC_TARGET_TO_TARGET(dc_target);
-+
-+ target->ref_count++;
-+}
-+
-+void dc_target_release(struct dc_target *dc_target)
-+{
-+ struct target *target = DC_TARGET_TO_TARGET(dc_target);
-+ struct core_target *protected = DC_TARGET_TO_CORE(dc_target);
-+
-+ ASSERT(target->ref_count > 0);
-+ target->ref_count--;
-+ if (target->ref_count == 0) {
-+ destruct(protected);
-+ dc_service_free(protected->ctx, target);
-+ }
-+}
-+
-+const struct dc_target_status *dc_target_get_status(
-+ const struct dc_target* dc_target)
-+{
-+ struct core_target* target = DC_TARGET_TO_CORE(dc_target);
-+ return &target->status;
-+}
-+
-+struct dc_target *dc_create_target_for_streams(
-+ struct dc_stream *dc_streams[],
-+ uint8_t stream_count)
-+{
-+ struct core_stream *stream;
-+ struct target *target;
-+
-+ if (0 == stream_count)
-+ goto target_alloc_fail;
-+
-+ stream = DC_STREAM_TO_CORE(dc_streams[0]);
-+
-+ target = dc_service_alloc(stream->ctx, sizeof(struct target));
-+
-+ if (NULL == target)
-+ goto target_alloc_fail;
-+
-+ construct(&target->protected, stream->ctx, dc_streams, stream_count);
-+
-+ dc_target_retain(&target->protected.public);
-+
-+ return &target->protected.public;
-+
-+
-+target_alloc_fail:
-+ return NULL;
-+}
-+
-+static void build_gamma_params(
-+ enum pixel_format pixel_format,
-+ struct gamma_parameters *gamma_param)
-+{
-+ uint32_t i;
-+
-+ /* translate parameters */
-+ gamma_param->surface_pixel_format = pixel_format;
-+
-+ gamma_param->regamma_adjust_type = GRAPHICS_REGAMMA_ADJUST_SW;
-+ gamma_param->degamma_adjust_type = GRAPHICS_REGAMMA_ADJUST_SW;
-+
-+ gamma_param->selected_gamma_lut = GRAPHICS_GAMMA_LUT_LEGACY;
-+
-+ /* TODO support non-legacy gamma */
-+ gamma_param->disable_adjustments = false;
-+ gamma_param->flag.bits.config_is_changed = 0;
-+ gamma_param->flag.bits.regamma_update = 1;
-+ gamma_param->flag.bits.gamma_update = 1;
-+
-+ /* Set regamma */
-+ gamma_param->regamma.features.bits.GRAPHICS_DEGAMMA_SRGB = 0;
-+ gamma_param->regamma.features.bits.OVERLAY_DEGAMMA_SRGB = 0;
-+ gamma_param->regamma.features.bits.GAMMA_RAMP_ARRAY = 0;
-+ gamma_param->regamma.features.bits.APPLY_DEGAMMA = 0;
-+
-+ for (i = 0; i < COEFF_RANGE; i++) {
-+ gamma_param->regamma.gamma_coeff.a0[i] = REGAMMA_COEFF_A0;
-+ gamma_param->regamma.gamma_coeff.a1[i] = REGAMMA_COEFF_A1;
-+ gamma_param->regamma.gamma_coeff.a2[i] = REGAMMA_COEFF_A2;
-+ gamma_param->regamma.gamma_coeff.a3[i] = REGAMMA_COEFF_A3;
-+ gamma_param->regamma.gamma_coeff.gamma[i] = REGAMMA_COEFF_GAMMA;
-+ }
-+}
-+
-+
-+static bool program_gamma(
-+ struct dc_context *ctx,
-+ struct dc_surface *surface,
-+ struct input_pixel_processor *ipp,
-+ struct output_pixel_processor *opp)
-+{
-+ struct gamma_parameters *gamma_param;
-+ bool result= false;
-+
-+ gamma_param = dc_service_alloc(ctx, sizeof(struct gamma_parameters));
-+
-+ if (!gamma_param)
-+ goto gamma_param_fail;
-+
-+ build_gamma_params(surface->format, gamma_param);
-+
-+ result = ctx->dc->hwss.set_gamma_ramp(ipp, opp,
-+ &surface->gamma_correction,
-+ gamma_param);
-+
-+ dc_service_free(ctx, gamma_param);
-+
-+gamma_param_fail:
-+ return result;
-+}
-+
-+bool dc_commit_surfaces_to_target(
-+ struct dc *dc,
-+ struct dc_surface *surfaces[],
-+ uint8_t surface_count,
-+ struct dc_target *dc_target)
-+
-+{
-+ uint8_t i, j;
-+ struct core_target *target = DC_TARGET_TO_CORE(dc_target);
-+ bool need_blanking = (target->status.surface_count == 0);
-+
-+ dal_logger_write(dc->ctx->logger,
-+ LOG_MAJOR_INTERFACE_TRACE,
-+ LOG_MINOR_COMPONENT_DC,
-+ "%s: commit %d surfaces to target 0x%x",
-+ __func__,
-+ surface_count,
-+ dc_target);
-+
-+
-+ if (!logical_attach_surfaces_to_target(
-+ surfaces,
-+ surface_count,
-+ dc_target)) {
-+ BREAK_TO_DEBUGGER();
-+ goto unexpected_fail;
-+ }
-+
-+ for (i = 0; i < surface_count; i++)
-+ for (j = 0; j < target->stream_count; j++)
-+ build_scaling_params(surfaces[i], target->streams[j]);
-+
-+ if (dc->hwss.validate_bandwidth(dc, &dc->current_context) != DC_OK) {
-+ BREAK_TO_DEBUGGER();
-+ goto unexpected_fail;
-+ }
-+
-+ dc->hwss.program_bw(dc, &dc->current_context);
-+
-+ if (need_blanking)
-+ dc_target_disable_memory_requests(dc_target);
-+
-+ for (i = 0; i < surface_count; i++) {
-+ struct dc_surface *surface = surfaces[i];
-+ struct core_surface *core_surface = DC_SURFACE_TO_CORE(surface);
-+
-+ dal_logger_write(dc->ctx->logger,
-+ LOG_MAJOR_INTERFACE_TRACE,
-+ LOG_MINOR_COMPONENT_DC,
-+ "0x%x:",
-+ surface);
-+ dc_surface_retain(surface);
-+
-+ program_gamma(dc->ctx, surface,
-+ target->streams[0]->ipp,
-+ target->streams[0]->opp);
-+
-+ dc->hwss.set_plane_config(
-+ core_surface,
-+ target);
-+
-+ dc->hwss.update_plane_address(core_surface, target);
-+ }
-+
-+ if (surface_count > 0 && need_blanking)
-+ dc_target_enable_memory_requests(dc_target);
-+
-+ return true;
-+
-+unexpected_fail:
-+ for (i = 0; i < surface_count; i++) {
-+ target->status.surfaces[i] = NULL;
-+ }
-+ target->status.surface_count = 0;
-+
-+ return false;
-+}
-+
-+bool dc_target_is_connected_to_sink(
-+ const struct dc_target * dc_target,
-+ const struct dc_sink *dc_sink)
-+{
-+ struct core_target *target = DC_TARGET_TO_CORE(dc_target);
-+ uint8_t i;
-+ for (i = 0; i < target->stream_count; i++) {
-+ if (&target->streams[i]->sink->public == dc_sink)
-+ return true;
-+ }
-+ return false;
-+}
-+
-+void dc_target_enable_memory_requests(struct dc_target *target)
-+{
-+ uint8_t i;
-+ struct core_target *core_target = DC_TARGET_TO_CORE(target);
-+ for (i = 0; i < core_target->stream_count; i++) {
-+ struct timing_generator *tg = core_target->streams[i]->tg;
-+ if (false == core_target->ctx->dc->hwss.enable_memory_requests(tg)) {
-+ dal_error("DC: failed to unblank crtc!\n");
-+ BREAK_TO_DEBUGGER();
-+ }
-+ }
-+}
-+
-+void dc_target_disable_memory_requests(struct dc_target *target)
-+{
-+ uint8_t i;
-+ struct core_target *core_target = DC_TARGET_TO_CORE(target);
-+ for (i = 0; i < core_target->stream_count; i++) {
-+ struct timing_generator *tg = core_target->streams[i]->tg;
-+
-+ if (NULL == tg) {
-+ dal_error("DC: timing generator is NULL!\n");
-+ BREAK_TO_DEBUGGER();
-+ continue;
-+ }
-+
-+ if (false == core_target->ctx->dc->hwss.disable_memory_requests(tg)) {
-+ dal_error("DC: failed to blank crtc!\n");
-+ BREAK_TO_DEBUGGER();
-+ }
-+ }
-+}
-+
-+/**
-+ * Update the cursor attributes and set cursor surface address
-+ */
-+bool dc_target_set_cursor_attributes(
-+ struct dc_target *dc_target,
-+ const struct dc_cursor_attributes *attributes)
-+{
-+ struct core_target *core_target;
-+ struct input_pixel_processor *ipp;
-+
-+ if (NULL == dc_target) {
-+ dal_error("DC: dc_target is NULL!\n");
-+ return false;
-+
-+ }
-+
-+ core_target = DC_TARGET_TO_CORE(dc_target);
-+ ipp = core_target->streams[0]->ipp;
-+
-+ if (NULL == ipp) {
-+ dal_error("DC: input pixel processor is NULL!\n");
-+ return false;
-+ }
-+
-+ if (true == core_target->ctx->dc->hwss.cursor_set_attributes(ipp, attributes))
-+ return true;
-+
-+ return false;
-+}
-+
-+bool dc_target_set_cursor_position(
-+ struct dc_target *dc_target,
-+ const struct dc_cursor_position *position)
-+{
-+ struct core_target *core_target;
-+ struct input_pixel_processor *ipp;
-+
-+ if (NULL == dc_target) {
-+ dal_error("DC: dc_target is NULL!\n");
-+ return false;
-+ }
-+
-+ if (NULL == position) {
-+ dal_error("DC: cursor position is NULL!\n");
-+ return false;
-+ }
-+
-+ core_target = DC_TARGET_TO_CORE(dc_target);
-+ ipp = core_target->streams[0]->ipp;
-+
-+ if (NULL == ipp) {
-+ dal_error("DC: input pixel processor is NULL!\n");
-+ return false;
-+ }
-+
-+
-+ if (true == core_target->ctx->dc->hwss.cursor_set_position(ipp, position))
-+ return true;
-+
-+ return false;
-+}
-+
-+/* TODO: #flip temporary to make flip work */
-+uint8_t dc_target_get_link_index(const struct dc_target *dc_target)
-+{
-+ const struct core_target *target = CONST_DC_TARGET_TO_CORE(dc_target);
-+
-+ return target->streams[0]->sink->link->link_index;
-+}
-+
-+uint32_t dc_target_get_vblank_counter(const struct dc_target *dc_target)
-+{
-+ struct core_target *core_target = DC_TARGET_TO_CORE(dc_target);
-+ struct timing_generator *tg = core_target->streams[0]->tg;
-+
-+ return core_target->ctx->dc->hwss.get_vblank_counter(tg);
-+}
-+
-+enum dc_irq_source dc_target_get_irq_src(
-+ const struct dc_target *dc_target, const enum irq_type irq_type)
-+{
-+ struct core_target *core_target = DC_TARGET_TO_CORE(dc_target);
-+
-+ /* #TODO - Remove the assumption that the controller is always in the
-+ * first stream of a core target */
-+ uint8_t controller_idx = core_target->streams[0]->controller_idx;
-+
-+ /* Get controller id */
-+ enum controller_id crtc_id = controller_idx + 1;
-+
-+ /* Calculate controller offset */
-+ unsigned int offset = crtc_id - CONTROLLER_ID_D0;
-+ unsigned int base = irq_type;
-+
-+ /* Calculate irq source */
-+ enum dc_irq_source src = base + offset;
-+
-+ return src;
-+}
-+
-+void dc_target_log(
-+ const struct dc_target *dc_target,
-+ struct dal_logger *dal_logger,
-+ enum log_major log_major,
-+ enum log_minor log_minor)
-+{
-+ int i;
-+
-+ const struct core_target *core_target =
-+ CONST_DC_TARGET_TO_CORE(dc_target);
-+
-+ dal_logger_write(dal_logger,
-+ log_major,
-+ log_minor,
-+ "core_target 0x%x: surface_count=%d, stream_count=%d",
-+ core_target,
-+ core_target->status.surface_count,
-+ core_target->stream_count);
-+
-+ for (i = 0; i < core_target->stream_count; i++) {
-+ const struct core_stream *core_stream = core_target->streams[i];
-+
-+ dal_logger_write(dal_logger,
-+ log_major,
-+ log_minor,
-+ "core_stream 0x%x: src: %d, %d, %d, %d; dst: %d, %d, %d, %d;",
-+ core_stream,
-+ core_stream->public.src.x,
-+ core_stream->public.src.y,
-+ core_stream->public.src.width,
-+ core_stream->public.src.height,
-+ core_stream->public.dst.x,
-+ core_stream->public.dst.y,
-+ core_stream->public.dst.width,
-+ core_stream->public.dst.height);
-+ dal_logger_write(dal_logger,
-+ log_major,
-+ log_minor,
-+ "\tpix_clk_khz: %d, h_total: %d, v_total: %d",
-+ core_stream->public.timing.pix_clk_khz,
-+ core_stream->public.timing.h_total,
-+ core_stream->public.timing.v_total);
-+ dal_logger_write(dal_logger,
-+ log_major,
-+ log_minor,
-+ "\tsink name: %s, serial: %d",
-+ core_stream->sink->public.edid_caps.display_name,
-+ core_stream->sink->public.edid_caps.serial_number);
-+ dal_logger_write(dal_logger,
-+ log_major,
-+ log_minor,
-+ "\tconnector: %d",
-+ core_stream->sink->link->connector_index);
-+ }
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dc.h b/drivers/gpu/drm/amd/dal/dc/dc.h
-new file mode 100644
-index 0000000..1db9395
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dc.h
-@@ -0,0 +1,440 @@
-+/*
-+ * Copyright 2012-14 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef DC_INTERFACE_H_
-+#define DC_INTERFACE_H_
-+
-+#include "dc_types.h"
-+/* TODO: We should not include audio_interface.h here. Maybe just define
-+ * struct audio_info here */
-+#include "audio_interface.h"
-+#include "logger_types.h"
-+
-+#define MAX_SINKS_PER_LINK 4
-+
-+/*******************************************************************************
-+ * Display Core Interfaces
-+ ******************************************************************************/
-+struct dc_init_data {
-+ struct dc_context *ctx;
-+ struct adapter_service *adapter_srv;
-+};
-+
-+struct dc_caps {
-+ uint32_t max_targets;
-+ uint32_t max_links;
-+ uint32_t max_audios;
-+};
-+
-+void dc_get_caps(const struct dc *dc, struct dc_caps *caps);
-+
-+struct dc *dc_create(const struct dal_init_data *init_params);
-+void dc_destroy(struct dc **dc);
-+
-+/*******************************************************************************
-+ * Surface Interfaces
-+ ******************************************************************************/
-+
-+struct dc_surface {
-+ bool enabled;
-+ bool flip_immediate;
-+ struct dc_plane_address address;
-+
-+ struct scaling_taps scaling_quality;
-+ struct rect src_rect;
-+ struct rect dst_rect;
-+ struct rect clip_rect;
-+
-+ union plane_size plane_size;
-+ union plane_tiling_info tiling_info;
-+ struct plane_colorimetry colorimetry;
-+
-+ enum surface_pixel_format format;
-+ enum dc_rotation_angle rotation;
-+ enum plane_stereo_format stereo_format;
-+
-+ struct gamma_ramp gamma_correction;
-+};
-+
-+/*
-+ * This structure is filled in by dc_surface_get_status and contains
-+ * the last requested address and the currently active address so the called
-+ * can determine if there are any outstanding flips
-+ */
-+struct dc_surface_status {
-+ struct dc_plane_address requested_address;
-+ struct dc_plane_address current_address;
-+ const struct dc_target *dc_target;
-+};
-+
-+/*
-+ * Create a new surface with default parameters;
-+ */
-+struct dc_surface *dc_create_surface(const struct dc *dc);
-+const struct dc_surface_status* dc_surface_get_status(
-+ struct dc_surface *dc_surface);
-+
-+void dc_surface_retain(const struct dc_surface *dc_surface);
-+void dc_surface_release(const struct dc_surface *dc_surface);
-+
-+/*
-+ * This structure holds a surface address. There could be multiple addresses
-+ * in cases such as Stereo 3D, Planar YUV, etc. Other per-flip attributes such
-+ * as frame durations and DCC format can also be set.
-+ */
-+struct dc_flip_addrs {
-+ struct dc_plane_address address;
-+
-+ /* TODO: DCC format info */
-+ /* TODO: add flip duration for FreeSync */
-+};
-+
-+/*
-+ * Optimized flip address update function.
-+ *
-+ * After this call:
-+ * Surface addresses and flip attributes are programmed.
-+ * Surface flip occur at next configured time (h_sync or v_sync flip)
-+ */
-+void dc_flip_surface_addrs(struct dc* dc,
-+ const struct dc_surface *const surfaces[],
-+ struct dc_flip_addrs flip_addrs[],
-+ uint32_t count);
-+
-+/*
-+ * Set up surface attributes and associate to a target
-+ * The surfaces parameter is an absolute set of all surface active for the target.
-+ * If no surfaces are provided, the target will be blanked; no memory read.
-+ * Any flip related attribute changes must be done through this interface.
-+ *
-+ * After this call:
-+ * Surfaces attributes are programmed and configured to be composed into target.
-+ * This does not trigger a flip. No surface address is programmed.
-+ */
-+bool dc_commit_surfaces_to_target(
-+ struct dc *dc,
-+ struct dc_surface *dc_surfaces[],
-+ uint8_t surface_count,
-+ struct dc_target *dc_target);
-+
-+/*******************************************************************************
-+ * Target Interfaces
-+ ******************************************************************************/
-+#define MAX_STREAM_NUM 1
-+
-+struct dc_target {
-+ uint32_t temp;
-+ const struct dc_stream *streams[MAX_STREAM_NUM];
-+};
-+
-+/*
-+ * Target status is returned from dc_target_get_status in order to get the
-+ * the IRQ source, current frame counter and currently attached surfaces.
-+ */
-+struct dc_target_status {
-+ enum dc_irq_source page_flip_src;
-+ enum dc_irq_source v_update_src;
-+ uint32_t cur_frame_count;
-+ const struct dc_surface *surfaces[MAX_SURFACE_NUM];
-+ uint8_t surface_count;
-+};
-+
-+struct dc_target *dc_create_target_for_streams(
-+ struct dc_stream *dc_streams[],
-+ uint8_t stream_count);
-+
-+/*
-+ * Get the current target status.
-+ */
-+const struct dc_target_status *dc_target_get_status(
-+ const struct dc_target* dc_target);
-+
-+void dc_target_retain(struct dc_target *dc_target);
-+void dc_target_release(struct dc_target *dc_target);
-+void dc_target_log(
-+ const struct dc_target *dc_target,
-+ struct dal_logger *dal_logger,
-+ enum log_major log_major,
-+ enum log_minor log_minor);
-+
-+uint8_t dc_get_current_target_count(const struct dc *dc);
-+struct dc_target *dc_get_target_at_index(const struct dc *dc, uint8_t i);
-+
-+bool dc_target_is_connected_to_sink(
-+ const struct dc_target *dc_target,
-+ const struct dc_sink *dc_sink);
-+
-+uint8_t dc_target_get_link_index(const struct dc_target *dc_target);
-+uint8_t dc_target_get_controller_id(const struct dc_target *dc_target);
-+
-+uint32_t dc_target_get_vblank_counter(const struct dc_target *dc_target);
-+enum dc_irq_source dc_target_get_irq_src(
-+ const struct dc_target *dc_target, const enum irq_type irq_type);
-+
-+void dc_target_enable_memory_requests(struct dc_target *target);
-+void dc_target_disable_memory_requests(struct dc_target *target);
-+
-+/*
-+ * Structure to store surface/target associations for validation
-+ */
-+struct dc_validation_set {
-+ const struct dc_target *target;
-+ const struct dc_surface *surfaces[4];
-+ uint8_t surface_count;
-+};
-+
-+/*
-+ * This function takes a set of resources and checks that they are cofunctional.
-+ *
-+ * After this call:
-+ * No hardware is programmed for call. Only validation is done.
-+ */
-+bool dc_validate_resources(
-+ const struct dc *dc,
-+ const struct dc_validation_set set[],
-+ uint8_t set_count);
-+
-+/*
-+ * Set up streams and links associated to targets to drive sinks
-+ * The targets parameter is an absolute set of all active targets.
-+ *
-+ * After this call:
-+ * Phy, Encoder, Timing Generator are programmed and enabled.
-+ * New targets are enabled with blank stream; no memory read.
-+ */
-+bool dc_commit_targets(
-+ struct dc *dc,
-+ struct dc_target *targets[],
-+ uint8_t target_count);
-+
-+/*******************************************************************************
-+ * Stream Interfaces
-+ ******************************************************************************/
-+struct dc_stream {
-+ const struct dc_sink *sink;
-+ struct dc_crtc_timing timing;
-+
-+ struct rect src; /* viewport in target space*/
-+ struct rect dst; /* stream addressable area */
-+
-+ struct audio_info audio_info;
-+
-+ /* TODO: dithering */
-+ /* TODO: transfer function (CSC/regamma/gamut remap) */
-+ /* TODO: custom INFO packets */
-+ /* TODO: DRR/Freesync parameters */
-+ /* TODO: ABM info (DMCU) */
-+ /* TODO: PSR info */
-+ /* TODO: CEA VIC */
-+};
-+
-+/**
-+ * Create a new default stream for the requested sink
-+ */
-+struct dc_stream *dc_create_stream_for_sink(const struct dc_sink *dc_sink);
-+
-+void dc_stream_retain(struct dc_stream *dc_stream);
-+void dc_stream_release(struct dc_stream *dc_stream);
-+
-+/*******************************************************************************
-+ * Link Interfaces
-+ ******************************************************************************/
-+
-+/*
-+ * A link contains one or more sinks and their connected status.
-+ * The currently active signal type (HDMI, DP-SST, DP-MST) is also reported.
-+ */
-+struct dc_link {
-+ const struct dc_sink *sink[MAX_SINKS_PER_LINK]; /* TODO: multiple sink support for MST */
-+ unsigned int sink_count;
-+ enum dc_connection_type type;
-+ enum signal_type connector_signal;
-+ enum dc_irq_source irq_source_hpd;
-+ enum dc_irq_source irq_source_hpd_rx;/* aka DP Short Pulse */
-+};
-+
-+/*
-+ * Return an enumerated dc_link. dc_link order is constant and determined at
-+ * boot time. They cannot be created or destroyed.
-+ * Use dc_get_caps() to get number of links.
-+ */
-+const struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index);
-+
-+/* Return id of physical connector represented by a dc_link at link_index.*/
-+const struct graphics_object_id dc_get_link_id_at_index(
-+ struct dc *dc, uint32_t link_index);
-+
-+/* Set backlight level of an embedded panel (eDP, LVDS). */
-+bool dc_link_set_backlight_level(const struct dc_link *dc_link, uint32_t level);
-+
-+/* Request DC to detect if there is a Panel connected. */
-+void dc_link_detect(const struct dc_link *dc_link);
-+
-+/* Notify DC about DP RX Interrupt (aka Short Pulse Interrupt).
-+ * Return:
-+ * true - Downstream port status changed. DM should call DC to do the
-+ * detection.
-+ * false - no change in Downstream port status. No further action required
-+ * from DM. */
-+bool dc_link_handle_hpd_rx_irq(const struct dc_link *dc_link);
-+
-+bool dc_link_add_sink(
-+ struct dc_link *link,
-+ struct dc_sink *sink
-+ );
-+
-+void dc_link_remove_sink(struct dc_link *link, const struct dc_sink *sink);
-+
-+/*******************************************************************************
-+ * Sink Interfaces - A sink corresponds to a display output device
-+ ******************************************************************************/
-+
-+/*
-+ * The sink structure contains EDID and other display device properties
-+ */
-+struct dc_sink {
-+ enum signal_type sink_signal;
-+ struct dc_edid dc_edid; /* raw edid */
-+ struct dc_edid_caps edid_caps; /* parse display caps */
-+};
-+
-+void dc_sink_retain(const struct dc_sink *sink);
-+void dc_sink_release(const struct dc_sink *sink);
-+
-+const struct audio **dc_get_audios(struct dc *dc);
-+
-+struct sink_init_data {
-+ enum signal_type sink_signal;
-+ struct dc_link *link;
-+ uint32_t dongle_max_pix_clk;
-+ bool converter_disable_audio;
-+};
-+
-+struct dc_sink *sink_create(const struct sink_init_data *init_params);
-+
-+
-+/*******************************************************************************
-+ * Cursor interfaces - To manages the cursor within a target
-+ ******************************************************************************/
-+struct dc_cursor {
-+ struct dc_plane_address address;
-+ struct dc_cursor_attributes attributes;
-+};
-+
-+/*
-+ * Create a new cursor with default values for a given target.
-+ */
-+struct dc_cursor *dc_create_cursor_for_target(
-+ const struct dc *dc,
-+ struct dc_target *dc_target);
-+
-+/**
-+ * Commit cursor attribute changes such as pixel format and dimensions and
-+ * surface address.
-+ *
-+ * After this call:
-+ * Cursor address and format is programmed to the new values.
-+ * Cursor position is unmodified.
-+ */
-+bool dc_commit_cursor(
-+ const struct dc *dc,
-+ struct dc_cursor *cursor);
-+
-+/*
-+ * Optimized cursor position update
-+ *
-+ * After this call:
-+ * Cursor position will be programmed as well as enable/disable bit.
-+ */
-+bool dc_set_cursor_position(
-+ const struct dc *dc,
-+ struct dc_cursor *cursor,
-+ struct dc_cursor_position *pos);
-+
-+
-+
-+/*******************************************************************************
-+ * Interrupt interfaces
-+ ******************************************************************************/
-+enum dc_irq_source dc_interrupt_to_irq_source(
-+ struct dc *dc,
-+ uint32_t src_id,
-+ uint32_t ext_id);
-+void dc_interrupt_set(const struct dc *dc, enum dc_irq_source src, bool enable);
-+void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src);
-+const enum dc_irq_source dc_get_hpd_irq_source_at_index(
-+ struct dc *dc, uint32_t link_index);
-+const struct dc_target *dc_get_target_on_irq_source(
-+ const struct dc *dc,
-+ enum dc_irq_source src);
-+
-+
-+/*******************************************************************************
-+ * Power Interfaces
-+ ******************************************************************************/
-+
-+void dc_set_power_state(
-+ struct dc *dc,
-+ enum dc_acpi_cm_power_state power_state,
-+ enum dc_video_power_state video_power_state);
-+void dc_resume(const struct dc *dc);
-+
-+/*******************************************************************************
-+ * DDC Interfaces
-+ ******************************************************************************/
-+
-+const struct ddc_service *dc_get_ddc_at_index(
-+ struct dc *dc, uint32_t link_index);
-+const struct dc_ddc* dc_get_ddc_from_sink(const struct dc_sink* sink);
-+const struct dc_ddc* dc_get_ddc_from_link(const struct dc_link* link);
-+bool dc_ddc_query_i2c(const struct dc_ddc* ddc,
-+ uint32_t address,
-+ uint8_t* write_buf,
-+ uint32_t write_size,
-+ uint8_t* read_buf,
-+ uint32_t read_size);
-+bool dc_ddc_dpcd_read(const struct dc_ddc* ddc, uint32_t address,
-+ uint8_t* data, uint32_t len);
-+bool dc_ddc_dpcd_write(const struct dc_ddc* ddc, uint32_t address,
-+ const uint8_t* data, uint32_t len);
-+
-+
-+
-+bool dc_read_dpcd(
-+ struct dc *dc,
-+ uint32_t link_index,
-+ uint32_t address,
-+ uint8_t *data,
-+ uint32_t size);
-+
-+bool dc_write_dpcd(
-+ struct dc *dc,
-+ uint32_t link_index,
-+ uint32_t address,
-+ uint8_t *data,
-+ uint32_t size);
-+
-+
-+#endif /* DC_INTERFACE_H_ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dc_helpers.h b/drivers/gpu/drm/amd/dal/dc/dc_helpers.h
-new file mode 100644
-index 0000000..c06eb8c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dc_helpers.h
-@@ -0,0 +1,75 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+/**
-+ * This file defines helper functions provided by the Display Manager to
-+ * Display Core.
-+ */
-+#ifndef __DC_HELPERS__
-+#define __DC_HELPERS__
-+
-+#include "dc_types.h"
-+#include "dc.h"
-+
-+enum dc_edid_status dc_helpers_parse_edid_caps(
-+ struct dc_context *ctx,
-+ const struct dc_edid *edid,
-+ struct dc_edid_caps *edid_caps);
-+
-+/*
-+ * Writes payload allocation table in immediate downstream device.
-+ */
-+bool dc_helpers_dp_mst_write_payload_allocation_table(
-+ struct dc_context *ctx,
-+ const struct dc_sink *sink,
-+ struct dp_mst_stream_allocation *alloc_entity,
-+ bool enable);
-+
-+/*
-+ * Polls for ACT (allocation change trigger) handled and
-+ */
-+bool dc_helpers_dp_mst_poll_for_allocation_change_trigger(
-+ struct dc_context *ctx,
-+ const struct dc_sink *sink);
-+/*
-+ * Sends ALLOCATE_PAYLOAD message.
-+ */
-+bool dc_helpers_dp_mst_send_payload_allocation(
-+ struct dc_context *ctx,
-+ const struct dc_sink *sink,
-+ bool enable);
-+
-+void dc_helpers_dp_mst_handle_mst_hpd_rx_irq(
-+ void *param);
-+
-+bool dc_helpers_dp_mst_start_top_mgr(
-+ struct dc_context *ctx,
-+ const struct dc_link *link);
-+
-+void dc_helpers_dp_mst_stop_top_mgr(
-+ struct dc_context *ctx,
-+ const struct dc_link *link);
-+
-+#endif /* __DC_HELPERS__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dc_services.h b/drivers/gpu/drm/amd/dal/dc/dc_services.h
-new file mode 100644
-index 0000000..f430864
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dc_services.h
-@@ -0,0 +1,174 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+/**
-+ * This file defines external dependencies of Display Core.
-+ */
-+
-+#ifndef __DC_SERVICES_H__
-+#define __DC_SERVICES_H__
-+
-+/* TODO: remove when DC is complete. */
-+#include "dal_services_types.h"
-+#include "include/dal_types.h"
-+#include "logger_interface.h"
-+#include "irq_types.h"
-+#include "dal_power_interface_types.h"
-+
-+
-+/* if the pointer is not NULL, the allocated memory is zeroed */
-+void *dc_service_alloc(struct dc_context *ctx, uint32_t size);
-+
-+void dc_service_free(struct dc_context *ctx, void *p);
-+
-+void dc_service_memset(void *p, int32_t c, uint32_t count);
-+
-+void dc_service_memmove(void *dst, const void *src, uint32_t size);
-+
-+/* TODO: rename to dc_memcmp*/
-+int32_t dal_memcmp(const void *p1, const void *p2, uint32_t count);
-+
-+/* TODO: remove when windows_dm will start registering for IRQs */
-+irq_handler_idx dc_service_register_interrupt(
-+ struct dc_context *ctx,
-+ struct dc_interrupt_params *int_params,
-+ interrupt_handler ih,
-+ void *handler_args);
-+
-+/* TODO: remove when windows_dm will start registering for IRQs */
-+void dc_service_unregister_interrupt(
-+ struct dc_context *ctx,
-+ enum dc_irq_source irq_source,
-+ irq_handler_idx handler_idx);
-+
-+/**************************************
-+ * Calls to Power Play (PP) component
-+ **************************************/
-+
-+/* DAL calls this function to notify PP about clocks it needs for the Mode Set.
-+ * This is done *before* it changes DCE clock.
-+ *
-+ * If required clock is higher than current, then PP will increase the voltage.
-+ *
-+ * If required clock is lower than current, then PP will defer reduction of
-+ * voltage until the call to dc_service_pp_post_dce_clock_change().
-+ *
-+ * \input - Contains clocks needed for Mode Set.
-+ *
-+ * \output - Contains clocks adjusted by PP which DAL should use for Mode Set.
-+ * Valid only if function returns zero.
-+ *
-+ * \returns true - call is successful
-+ * false - call failed
-+ */
-+bool dc_service_pp_pre_dce_clock_change(
-+ struct dc_context *ctx,
-+ struct dal_to_power_info *input,
-+ struct power_to_dal_info *output);
-+
-+struct dc_pp_display_configuration {
-+ bool nb_pstate_switch_disable;/* controls NB PState switch */
-+ bool cpu_cc6_disable; /* controls CPU CState switch ( on or off) */
-+ bool cpu_pstate_disable;
-+ uint32_t cpu_pstate_separation_time;
-+};
-+
-+/* DAL calls this function to notify PP about completion of Mode Set.
-+ * For PP it means that current DCE clocks are those which were returned
-+ * by dc_service_pp_pre_dce_clock_change(), in the 'output' parameter.
-+ *
-+ * If the clocks are higher than before, then PP does nothing.
-+ *
-+ * If the clocks are lower than before, then PP reduces the voltage.
-+ *
-+ * \returns true - call is successful
-+ * false - call failed
-+ */
-+bool dc_service_pp_post_dce_clock_change(
-+ struct dc_context *ctx,
-+ const struct dc_pp_display_configuration *pp_display_cfg);
-+
-+/* The returned clocks range are 'static' system clocks which will be used for
-+ * mode validation purposes.
-+ *
-+ * \returns true - call is successful
-+ * false - call failed
-+ */
-+bool dc_service_get_system_clocks_range(
-+ struct dc_context *ctx,
-+ struct dal_system_clock_range *sys_clks);
-+
-+/* for future use */
-+bool dc_service_pp_set_display_clock(
-+ struct dc_context *ctx,
-+ struct dal_to_power_dclk *dclk);
-+
-+void dc_service_sleep_in_milliseconds(struct dc_context *ctx, uint32_t milliseconds);
-+
-+/* end of power component calls */
-+
-+void dc_service_delay_in_microseconds(struct dc_context *ctx, uint32_t microseconds);
-+
-+/*
-+ *
-+ * general debug capabilities
-+ *
-+ */
-+#if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER)
-+
-+#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
-+#define ASSERT_CRITICAL(expr) do { \
-+ if (WARN_ON(!(expr))) { \
-+ kgdb_breakpoint(); \
-+ } \
-+} while (0)
-+#else
-+#define ASSERT_CRITICAL(expr) do { \
-+ if (WARN_ON(!(expr))) { \
-+ ; \
-+ } \
-+} while (0)
-+#endif
-+
-+#if defined(CONFIG_DEBUG_KERNEL_DAL)
-+#define ASSERT(expr) ASSERT_CRITICAL(expr)
-+
-+#else
-+#define ASSERT(expr) WARN_ON(!(expr))
-+#endif
-+
-+#define BREAK_TO_DEBUGGER() ASSERT(0)
-+
-+#else
-+
-+#define ASSERT_CRITICAL(expr) do {if (expr)/* Do nothing */; } while (0)
-+
-+#define ASSERT(expr) do {if (expr)/* Do nothing */; } while (0)
-+
-+#define BREAK_TO_DEBUGGER() do {} while (0)
-+
-+#endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
-+
-+#endif /* __DC_SERVICES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dc_temp.h b/drivers/gpu/drm/amd/dal/dc/dc_temp.h
-new file mode 100644
-index 0000000..b609deb
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dc_temp.h
-@@ -0,0 +1,508 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef DC_TEMP_H_
-+#define DC_TEMP_H_
-+
-+#include "dc_types.h"
-+
-+#define MAX_SURFACE_NUM 2
-+
-+enum clamping_range {
-+ CLAMPING_FULL_RANGE = 0, /* No Clamping */
-+ CLAMPING_LIMITED_RANGE_8BPC, /* 8 bpc: Clamping 1 to FE */
-+ CLAMPING_LIMITED_RANGE_10BPC, /* 10 bpc: Clamping 4 to 3FB */
-+ CLAMPING_LIMITED_RANGE_12BPC, /* 12 bpc: Clamping 10 to FEF */
-+ /* Use programmable clampping value on FMT_CLAMP_COMPONENT_R/G/B. */
-+ CLAMPING_LIMITED_RANGE_PROGRAMMABLE
-+};
-+
-+struct clamping_and_pixel_encoding_params {
-+ enum dc_pixel_encoding pixel_encoding; /* Pixel Encoding */
-+ enum clamping_range clamping_level; /* Clamping identifier */
-+ enum dc_color_depth c_depth; /* Deep color use. */
-+};
-+
-+struct bit_depth_reduction_params {
-+ struct {
-+ /* truncate/round */
-+ /* trunc/round enabled*/
-+ uint32_t TRUNCATE_ENABLED:1;
-+ /* 2 bits: 0=6 bpc, 1=8 bpc, 2 = 10bpc*/
-+ uint32_t TRUNCATE_DEPTH:2;
-+ /* truncate or round*/
-+ uint32_t TRUNCATE_MODE:1;
-+
-+ /* spatial dither */
-+ /* Spatial Bit Depth Reduction enabled*/
-+ uint32_t SPATIAL_DITHER_ENABLED:1;
-+ /* 2 bits: 0=6 bpc, 1 = 8 bpc, 2 = 10bpc*/
-+ uint32_t SPATIAL_DITHER_DEPTH:2;
-+ /* 0-3 to select patterns*/
-+ uint32_t SPATIAL_DITHER_MODE:2;
-+ /* Enable RGB random dithering*/
-+ uint32_t RGB_RANDOM:1;
-+ /* Enable Frame random dithering*/
-+ uint32_t FRAME_RANDOM:1;
-+ /* Enable HighPass random dithering*/
-+ uint32_t HIGHPASS_RANDOM:1;
-+
-+ /* temporal dither*/
-+ /* frame modulation enabled*/
-+ uint32_t FRAME_MODULATION_ENABLED:1;
-+ /* same as for trunc/spatial*/
-+ uint32_t FRAME_MODULATION_DEPTH:2;
-+ /* 2/4 gray levels*/
-+ uint32_t TEMPORAL_LEVEL:1;
-+ uint32_t FRC25:2;
-+ uint32_t FRC50:2;
-+ uint32_t FRC75:2;
-+ } flags;
-+
-+ uint32_t r_seed_value;
-+ uint32_t b_seed_value;
-+ uint32_t g_seed_value;
-+};
-+
-+enum pipe_gating_control {
-+ PIPE_GATING_CONTROL_DISABLE = 0,
-+ PIPE_GATING_CONTROL_ENABLE,
-+ PIPE_GATING_CONTROL_INIT
-+};
-+
-+enum surface_color_space {
-+ SURFACE_COLOR_SPACE_SRGB = 0x0000,
-+ SURFACE_COLOR_SPACE_BT601 = 0x0001,
-+ SURFACE_COLOR_SPACE_BT709 = 0x0002,
-+ SURFACE_COLOR_SPACE_XVYCC_BT601 = 0x0004,
-+ SURFACE_COLOR_SPACE_XVYCC_BT709 = 0x0008,
-+ SURFACE_COLOR_SPACE_XRRGB = 0x0010
-+};
-+
-+enum {
-+ MAX_LANES = 2,
-+ MAX_COFUNC_PATH = 6,
-+ LAYER_INDEX_PRIMARY = -1,
-+};
-+
-+/* Scaling format */
-+enum scaling_transformation {
-+ SCALING_TRANSFORMATION_UNINITIALIZED,
-+ SCALING_TRANSFORMATION_IDENTITY = 0x0001,
-+ SCALING_TRANSFORMATION_CENTER_TIMING = 0x0002,
-+ SCALING_TRANSFORMATION_FULL_SCREEN_SCALE = 0x0004,
-+ SCALING_TRANSFORMATION_PRESERVE_ASPECT_RATIO_SCALE = 0x0008,
-+ SCALING_TRANSFORMATION_DAL_DECIDE = 0x0010,
-+ SCALING_TRANSFORMATION_INVALID = 0x80000000,
-+
-+ /* Flag the first and last */
-+ SCALING_TRANSFORMATION_BEGING = SCALING_TRANSFORMATION_IDENTITY,
-+ SCALING_TRANSFORMATION_END =
-+ SCALING_TRANSFORMATION_PRESERVE_ASPECT_RATIO_SCALE
-+};
-+
-+struct view_stereo_3d_support {
-+ enum view_3d_format format;
-+ struct {
-+ uint32_t CLONE_MODE:1;
-+ uint32_t SCALING:1;
-+ uint32_t SINGLE_FRAME_SW_PACKED:1;
-+ } features;
-+};
-+
-+struct plane_colorimetry {
-+ enum surface_color_space color_space;
-+ bool limited_range;
-+};
-+
-+enum tiling_mode {
-+ TILING_MODE_INVALID,
-+ TILING_MODE_LINEAR,
-+ TILING_MODE_TILED,
-+ TILING_MODE_COUNT
-+};
-+
-+struct view_position {
-+ uint32_t x;
-+ uint32_t y;
-+};
-+
-+union plane_tiling_info {
-+
-+ struct {
-+ /* Specifies the number of memory banks for tiling
-+ * purposes.
-+ * Only applies to 2D and 3D tiling modes.
-+ * POSSIBLE VALUES: 2,4,8,16
-+ */
-+ uint32_t NUM_BANKS:5;
-+ /* Specifies the number of tiles in the x direction
-+ * to be incorporated into the same bank.
-+ * Only applies to 2D and 3D tiling modes.
-+ * POSSIBLE VALUES: 1,2,4,8
-+ */
-+ uint32_t BANK_WIDTH:4;
-+ /* Specifies the number of tiles in the y direction to
-+ * be incorporated into the same bank.
-+ * Only applies to 2D and 3D tiling modes.
-+ * POSSIBLE VALUES: 1,2,4,8
-+ */
-+ uint32_t BANK_HEIGHT:4;
-+ /* Specifies the macro tile aspect ratio. Only applies
-+ * to 2D and 3D tiling modes.
-+ */
-+ uint32_t TILE_ASPECT:3;
-+ /* Specifies the number of bytes that will be stored
-+ * contiguously for each tile.
-+ * If the tile data requires more storage than this
-+ * amount, it is split into multiple slices.
-+ * This field must not be larger than
-+ * GB_ADDR_CONFIG.DRAM_ROW_SIZE.
-+ * Only applies to 2D and 3D tiling modes.
-+ * For color render targets, TILE_SPLIT >= 256B.
-+ */
-+ uint32_t TILE_SPLIT:3;
-+ /* Specifies the addressing within a tile.
-+ * 0x0 - DISPLAY_MICRO_TILING
-+ * 0x1 - THIN_MICRO_TILING
-+ * 0x2 - DEPTH_MICRO_TILING
-+ * 0x3 - ROTATED_MICRO_TILING
-+ */
-+ uint32_t TILE_MODE:2;
-+ /* Specifies the number of pipes and how they are
-+ * interleaved in the surface.
-+ * Refer to memory addressing document for complete
-+ * details and constraints.
-+ */
-+ uint32_t PIPE_CONFIG:5;
-+ /* Specifies the tiling mode of the surface.
-+ * THIN tiles use an 8x8x1 tile size.
-+ * THICK tiles use an 8x8x4 tile size.
-+ * 2D tiling modes rotate banks for successive Z slices
-+ * 3D tiling modes rotate pipes and banks for Z slices
-+ * Refer to memory addressing document for complete
-+ * details and constraints.
-+ */
-+ uint32_t ARRAY_MODE:4;
-+ } grph;
-+
-+
-+ struct {
-+ /*possible values: 2,4,8,16*/
-+ uint32_t NUM_BANKS:5;
-+ /*must use enum video_array_mode*/
-+ uint32_t ARRAY_MODE:4;
-+ /*must use enum addr_pipe_config*/
-+ uint32_t PIPE_CONFIG:5;
-+ /*possible values 1,2,4,8 */
-+ uint32_t BANK_WIDTH_LUMA:4;
-+ /*possible values 1,2,4,8 */
-+ uint32_t BANK_HEIGHT_LUMA:4;
-+ /*must use enum macro_tile_aspect*/
-+ uint32_t TILE_ASPECT_LUMA:3;
-+ /*must use enum tile_split*/
-+ uint32_t TILE_SPLIT_LUMA:3;
-+ /*must use micro_tile_mode */
-+ uint32_t TILE_MODE_LUMA:2;
-+ /*possible values: 1,2,4,8*/
-+ uint32_t BANK_WIDTH_CHROMA:4;
-+ /*possible values: 1,2,4,8*/
-+ uint32_t BANK_HEIGHT_CHROMA:4;
-+ /*must use enum macro_tile_aspect*/
-+ uint32_t TILE_ASPECT_CHROMA:3;
-+ /*must use enum tile_split*/
-+ uint32_t TILE_SPLIT_CHROMA:3;
-+ /*must use enum micro_tile_mode*/
-+ uint32_t TILE_MODE_CHROMA:2;
-+
-+ } video;
-+
-+ uint64_t value;
-+};
-+
-+union plane_size {
-+ /* Grph or Video will be selected
-+ * based on format above:
-+ * Use Video structure if
-+ * format >= DalPixelFormat_VideoBegin
-+ * else use Grph structure
-+ */
-+ struct {
-+ struct rect surface_size;
-+ /* Graphic surface pitch in pixels.
-+ * In LINEAR_GENERAL mode, pitch
-+ * is 32 pixel aligned.
-+ */
-+ uint32_t surface_pitch;
-+ } grph;
-+
-+ struct {
-+ struct rect luma_size;
-+ /* Graphic surface pitch in pixels.
-+ * In LINEAR_GENERAL mode, pitch is
-+ * 32 pixel aligned.
-+ */
-+ uint32_t luma_pitch;
-+
-+ struct rect chroma_size;
-+ /* Graphic surface pitch in pixels.
-+ * In LINEAR_GENERAL mode, pitch is
-+ * 32 pixel aligned.
-+ */
-+ uint32_t chroma_pitch;
-+ } video;
-+};
-+
-+/* Windows only */
-+enum dc_scaling_transform {
-+ SCL_TRANS_CENTERED = 0,
-+ SCL_TRANS_ASPECT_RATIO,
-+ SCL_TRANS_FULL
-+};
-+
-+struct dev_c_lut {
-+ uint8_t red;
-+ uint8_t green;
-+ uint8_t blue;
-+};
-+
-+struct dev_c_lut16 {
-+ uint16_t red;
-+ uint16_t green;
-+ uint16_t blue;
-+};
-+
-+enum gamma_ramp_type {
-+ GAMMA_RAMP_UNINITIALIZED = 0,
-+ GAMMA_RAMP_DEFAULT,
-+ GAMMA_RAMP_RBG256X3X16,
-+ GAMMA_RAMP_DXGI_1,
-+};
-+
-+enum surface_type {
-+ OVERLAY_SURFACE = 1, GRAPHIC_SURFACE
-+};
-+
-+#define CONST_RGB_GAMMA_VALUE 2400
-+
-+enum {
-+ RGB_256X3X16 = 256, DX_GAMMA_RAMP_MAX = 1025
-+};
-+
-+struct gamma_ramp_rgb256x3x16 {
-+ uint16_t red[RGB_256X3X16];
-+ uint16_t green[RGB_256X3X16];
-+ uint16_t blue[RGB_256X3X16];
-+};
-+
-+struct dxgi_rgb {
-+ struct fixed32_32 red;
-+ struct fixed32_32 green;
-+ struct fixed32_32 blue;
-+};
-+
-+struct gamma_ramp_dxgi_1 {
-+ struct dxgi_rgb scale;
-+ struct dxgi_rgb offset;
-+ struct dxgi_rgb gamma_curve[DX_GAMMA_RAMP_MAX];
-+};
-+
-+struct gamma_ramp {
-+ enum gamma_ramp_type type;
-+ union {
-+ struct gamma_ramp_rgb256x3x16 gamma_ramp_rgb256x3x16;
-+ struct gamma_ramp_dxgi_1 gamma_ramp_dxgi1;
-+ };
-+ uint32_t size;
-+};
-+
-+struct regamma_ramp {
-+ uint16_t gamma[RGB_256X3X16 * 3];
-+};
-+
-+/* used by Graphics and Overlay gamma */
-+struct gamma_coeff {
-+ int32_t gamma[3];
-+ int32_t a0[3]; /* index 0 for red, 1 for green, 2 for blue */
-+ int32_t a1[3];
-+ int32_t a2[3];
-+ int32_t a3[3];
-+};
-+
-+struct regamma_lut {
-+ union {
-+ struct {
-+ uint32_t GRAPHICS_DEGAMMA_SRGB :1;
-+ uint32_t OVERLAY_DEGAMMA_SRGB :1;
-+ uint32_t GAMMA_RAMP_ARRAY :1;
-+ uint32_t APPLY_DEGAMMA :1;
-+ uint32_t RESERVED :28;
-+ } bits;
-+ uint32_t value;
-+ } features;
-+
-+ union {
-+ struct regamma_ramp regamma_ramp;
-+ struct gamma_coeff gamma_coeff;
-+ };
-+};
-+
-+union gamma_flag {
-+ struct {
-+ uint32_t config_is_changed :1;
-+ uint32_t both_pipe_req :1;
-+ uint32_t regamma_update :1;
-+ uint32_t gamma_update :1;
-+ uint32_t reserved :28;
-+ } bits;
-+ uint32_t u_all;
-+};
-+
-+enum graphics_regamma_adjust {
-+ GRAPHICS_REGAMMA_ADJUST_BYPASS = 0, GRAPHICS_REGAMMA_ADJUST_HW, /* without adjustments */
-+ GRAPHICS_REGAMMA_ADJUST_SW /* use adjustments */
-+};
-+
-+enum graphics_gamma_lut {
-+ GRAPHICS_GAMMA_LUT_LEGACY = 0, /* use only legacy LUT */
-+ GRAPHICS_GAMMA_LUT_REGAMMA, /* use only regamma LUT */
-+ GRAPHICS_GAMMA_LUT_LEGACY_AND_REGAMMA /* use legacy & regamma LUT's */
-+};
-+
-+enum graphics_degamma_adjust {
-+ GRAPHICS_DEGAMMA_ADJUST_BYPASS = 0, GRAPHICS_DEGAMMA_ADJUST_HW, /*without adjustments */
-+ GRAPHICS_DEGAMMA_ADJUST_SW /* use adjustments */
-+};
-+
-+struct gamma_parameters {
-+ union gamma_flag flag;
-+ enum pixel_format surface_pixel_format; /*OS surface pixel format*/
-+ struct regamma_lut regamma;
-+
-+ enum graphics_regamma_adjust regamma_adjust_type;
-+ enum graphics_degamma_adjust degamma_adjust_type;
-+
-+ enum graphics_gamma_lut selected_gamma_lut;
-+
-+ bool disable_adjustments;
-+
-+ /* here we grow with parameters if necessary */
-+};
-+
-+struct pixel_format_support {
-+ bool INDEX8 :1;
-+ bool RGB565 :1;
-+ bool ARGB8888 :1;
-+ bool ARGB2101010 :1;
-+ bool ARGB2101010_XRBIAS :1;
-+ bool FP16 :1;
-+};
-+
-+struct render_mode {
-+ struct view view;
-+ enum pixel_format pixel_format;
-+};
-+
-+struct refresh_rate {
-+ uint32_t field_rate;
-+ bool INTERLACED :1;
-+ bool VIDEO_OPTIMIZED_RATE :1;
-+};
-+
-+struct stereo_3d_view {
-+ enum view_3d_format view_3d_format;
-+ union {
-+ uint32_t raw;
-+ struct /*stereo_3d_view_flags*/
-+ {
-+ bool SINGLE_FRAME_SW_PACKED :1;
-+ bool EXCLUSIVE_3D :1;
-+ } bits;
-+ } flags;
-+};
-+
-+enum solution_importance {
-+ SOLUTION_IMPORTANCE_PREFERRED = 1,
-+ /* Means we want to use this solution
-+ * even in wide topology configurations*/
-+ SOLUTION_IMPORTANCE_SAFE,
-+ SOLUTION_IMPORTANCE_UNSAFE,
-+ SOLUTION_IMPORTANCE_DEFAULT
-+/* Temporary state , means Solution object
-+ * should define importance by itself
-+ */
-+};
-+
-+struct solution {
-+ const struct dc_mode_timing *dc_mode_timing;
-+ enum solution_importance importance;
-+ bool is_custom_mode;
-+ uint32_t scl_support[NUM_PIXEL_FORMATS];
-+ /* bit vector of the scaling that can be supported on the timing */
-+ uint32_t scl_support_guaranteed[NUM_PIXEL_FORMATS];
-+ /* subset of m_sclSupport that can be guaranteed supported */
-+};
-+
-+enum timing_select {
-+ TIMING_SELECT_DEFAULT,
-+ TIMING_SELECT_NATIVE_ONLY,
-+ TIMING_SELECT_PRESERVE_ASPECT
-+};
-+
-+enum downscale_state {
-+ DOWNSCALESTATE_DEFAULT, // Disabled, but not user selected
-+ DOWNSCALESTATE_DISABLED, // User disabled through CCC
-+ DOWNSCALESTATE_ENABLED // User enabled through CCC
-+};
-+struct scaling_support {
-+ bool IDENTITY :1;
-+ bool FULL_SCREEN_SCALE :1;
-+ bool PRESERVE_ASPECT_RATIO_SCALE :1;
-+ bool CENTER_TIMING :1;
-+};
-+
-+
-+/* TODO: combine the two cursor functions into one to make cursor
-+ * programming resistant to changes in OS call sequence. */
-+bool dc_target_set_cursor_attributes(
-+ struct dc_target *dc_target,
-+ const struct dc_cursor_attributes *attributes);
-+
-+bool dc_target_set_cursor_position(
-+ struct dc_target *dc_target,
-+ const struct dc_cursor_position *position);
-+
-+/******************************************************************************
-+ * TODO: these definitions only for Timing Sync feature bring-up. Remove
-+ * when the feature is complete.
-+ *****************************************************************************/
-+
-+#define MAX_TARGET_NUM 6
-+
-+void dc_print_sync_report(
-+ const struct dc *dc);
-+
-+/******************************************************************************/
-+
-+#endif /* DC_TEMP_H_ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dc_types.h b/drivers/gpu/drm/amd/dal/dc/dc_types.h
-new file mode 100644
-index 0000000..b6526e9
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dc_types.h
-@@ -0,0 +1,677 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef DC_TYPES_H_
-+#define DC_TYPES_H_
-+
-+#include "fixed32_32.h"
-+#include "fixed31_32.h"
-+#include "irq_types.h"
-+
-+/* forward declarations */
-+struct dc;
-+struct dc_surface;
-+struct dc_target;
-+struct dc_stream;
-+struct dc_link;
-+struct dc_sink;
-+struct dal;
-+
-+#define MAX_EDID_BUFFER_SIZE 512
-+
-+/*Displayable pixel format in fb*/
-+enum surface_pixel_format {
-+ SURFACE_PIXEL_FORMAT_GRPH_BEGIN = 0,
-+ /*TOBE REMOVED paletta 256 colors*/
-+ SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS =
-+ SURFACE_PIXEL_FORMAT_GRPH_BEGIN,
-+ /*16 bpp*/
-+ SURFACE_PIXEL_FORMAT_GRPH_ARGB1555,
-+ /*16 bpp*/
-+ SURFACE_PIXEL_FORMAT_GRPH_RGB565,
-+ /*32 bpp*/
-+ SURFACE_PIXEL_FORMAT_GRPH_ARGB8888,
-+ /*32 bpp swaped*/
-+ SURFACE_PIXEL_FORMAT_GRPH_BGRA8888,
-+
-+ SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010,
-+ /*swaped*/
-+ SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010,
-+ /*TOBE REMOVED swaped, XR_BIAS has no differance
-+ * for pixel layout than previous and we can
-+ * delete this after discusion*/
-+ SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS,
-+ /*64 bpp */
-+ SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616,
-+ /*swaped & float*/
-+ SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F,
-+ /*grow graphics here if necessary */
-+
-+ SURFACE_PIXEL_FORMAT_VIDEO_BEGIN,
-+ SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr =
-+ SURFACE_PIXEL_FORMAT_VIDEO_BEGIN,
-+ SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb,
-+ SURFACE_PIXEL_FORMAT_VIDEO_422_YCb,
-+ SURFACE_PIXEL_FORMAT_VIDEO_422_YCr,
-+ SURFACE_PIXEL_FORMAT_VIDEO_422_CbY,
-+ SURFACE_PIXEL_FORMAT_VIDEO_422_CrY,
-+ /*grow 422/420 video here if necessary */
-+ SURFACE_PIXEL_FORMAT_VIDEO_444_BEGIN,
-+ SURFACE_PIXEL_FORMAT_VIDEO_444_ACrYCb1555 =
-+ SURFACE_PIXEL_FORMAT_VIDEO_444_BEGIN,
-+ SURFACE_PIXEL_FORMAT_VIDEO_444_CrYCb565,
-+ SURFACE_PIXEL_FORMAT_VIDEO_444_ACrYCb4444,
-+ SURFACE_PIXEL_FORMAT_VIDEO_444_CbYCrA5551,
-+ SURFACE_PIXEL_FORMAT_VIDEO_444_ACrYCb8888,
-+ SURFACE_PIXEL_FORMAT_VIDEO_444_ACrYCb2101010,
-+ SURFACE_PIXEL_FORMAT_VIDEO_444_CbYCrA1010102
-+ /*grow 444 video here if necessary */
-+};
-+
-+
-+/* Pixel format */
-+enum pixel_format {
-+ /*graph*/
-+ PIXEL_FORMAT_UNINITIALIZED,
-+ PIXEL_FORMAT_INDEX8,
-+ PIXEL_FORMAT_RGB565,
-+ PIXEL_FORMAT_ARGB8888,
-+ PIXEL_FORMAT_ARGB2101010,
-+ PIXEL_FORMAT_ARGB2101010_XRBIAS,
-+ PIXEL_FORMAT_FP16,
-+ /*video*/
-+ PIXEL_FORMAT_420BPP12,
-+ PIXEL_FORMAT_422BPP16,
-+ PIXEL_FORMAT_444BPP16,
-+ PIXEL_FORMAT_444BPP32,
-+ /*end of pixel format definition*/
-+ PIXEL_FORMAT_INVALID,
-+
-+ PIXEL_FORMAT_GRPH_BEGIN = PIXEL_FORMAT_INDEX8,
-+ PIXEL_FORMAT_GRPH_END = PIXEL_FORMAT_FP16,
-+ PIXEL_FORMAT_VIDEO_BEGIN = PIXEL_FORMAT_420BPP12,
-+ PIXEL_FORMAT_VIDEO_END = PIXEL_FORMAT_444BPP32,
-+ PIXEL_FORMAT_UNKNOWN
-+};
-+
-+enum plane_stereo_format {
-+ PLANE_STEREO_FORMAT_NONE = 0,
-+ PLANE_STEREO_FORMAT_SIDE_BY_SIDE = 1,
-+ PLANE_STEREO_FORMAT_TOP_AND_BOTTOM = 2,
-+ PLANE_STEREO_FORMAT_FRAME_ALTERNATE = 3,
-+ PLANE_STEREO_FORMAT_ROW_INTERLEAVED = 5,
-+ PLANE_STEREO_FORMAT_COLUMN_INTERLEAVED = 6,
-+ PLANE_STEREO_FORMAT_CHECKER_BOARD = 7
-+};
-+
-+/* 3D format for view, typically define how L/R eye surface is arranged within
-+ * frames
-+ */
-+enum view_3d_format {
-+ VIEW_3D_FORMAT_NONE = 0,
-+ VIEW_3D_FORMAT_FRAME_SEQUENTIAL,
-+ VIEW_3D_FORMAT_SIDE_BY_SIDE,
-+ VIEW_3D_FORMAT_TOP_AND_BOTTOM,
-+ VIEW_3D_FORMAT_COUNT,
-+ VIEW_3D_FORMAT_FIRST = VIEW_3D_FORMAT_FRAME_SEQUENTIAL
-+};
-+
-+enum dc_pixel_encoding {
-+ PIXEL_ENCODING_UNDEFINED,
-+ PIXEL_ENCODING_RGB,
-+ PIXEL_ENCODING_YCBCR422,
-+ PIXEL_ENCODING_YCBCR444,
-+ PIXEL_ENCODING_YCBCR420,
-+ PIXEL_ENCODING_COUNT
-+};
-+
-+/* TODO: Find way to calculate number of bits
-+ * Please increase if pixel_format enum increases
-+ * num from PIXEL_FORMAT_INDEX8 to PIXEL_FORMAT_444BPP32
-+ */
-+#define NUM_PIXEL_FORMATS 10
-+
-+
-+
-+union large_integer {
-+ struct {
-+ uint32_t low_part;
-+ int32_t high_part;
-+ };
-+
-+ struct {
-+ uint32_t low_part;
-+ int32_t high_part;
-+ } u;
-+
-+ int64_t quad_part;
-+};
-+
-+#define PHYSICAL_ADDRESS_LOC union large_integer
-+
-+enum dc_edid_connector_type {
-+ EDID_CONNECTOR_UNKNOWN = 0,
-+ EDID_CONNECTOR_ANALOG = 1,
-+ EDID_CONNECTOR_DIGITAL = 10,
-+ EDID_CONNECTOR_DVI = 11,
-+ EDID_CONNECTOR_HDMIA = 12,
-+ EDID_CONNECTOR_MDDI = 14,
-+ EDID_CONNECTOR_DISPLAYPORT = 15
-+};
-+
-+enum dc_edid_status {
-+ EDID_OK,
-+ EDID_BAD_INPUT,
-+ EDID_NO_RESPONSE,
-+ EDID_BAD_CHECKSUM,
-+};
-+
-+/* audio capability from EDID*/
-+struct dc_cea_audio_mode {
-+ uint8_t format_code; /* ucData[0] [6:3]*/
-+ uint8_t channel_count; /* ucData[0] [2:0]*/
-+ uint8_t sample_rate; /* ucData[1]*/
-+ union {
-+ uint8_t sample_size; /* for LPCM*/
-+ /* for Audio Formats 2-8 (Max bit rate divided by 8 kHz)*/
-+ uint8_t max_bit_rate;
-+ uint8_t audio_codec_vendor_specific; /* for Audio Formats 9-15*/
-+ };
-+};
-+
-+struct dc_edid {
-+ uint32_t length;
-+ uint8_t raw_edid[MAX_EDID_BUFFER_SIZE];
-+};
-+
-+/* When speaker location data block is not available, DEFAULT_SPEAKER_LOCATION
-+ * is used. In this case we assume speaker location are: front left, front
-+ * right and front center. */
-+#define DEFAULT_SPEAKER_LOCATION 5
-+
-+#define DC_MAX_AUDIO_DESC_COUNT 16
-+
-+#define AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS 20
-+
-+struct dc_edid_caps {
-+ /* sink identification */
-+ uint16_t manufacturer_id;
-+ uint16_t product_id;
-+ uint32_t serial_number;
-+ uint8_t manufacture_week;
-+ uint8_t manufacture_year;
-+ uint8_t display_name[AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS];
-+
-+ /* audio caps */
-+ uint8_t speaker_flags;
-+ uint32_t audio_mode_count;
-+ struct dc_cea_audio_mode audio_modes[DC_MAX_AUDIO_DESC_COUNT];
-+ uint32_t audio_latency;
-+ uint32_t video_latency;
-+
-+ /*HDMI 2.0 caps*/
-+ uint8_t lte_340mcsc_scramble;
-+};
-+
-+struct scaling_taps {
-+ uint32_t v_taps;
-+ uint32_t h_taps;
-+ uint32_t v_taps_c;
-+ uint32_t h_taps_c;
-+};
-+
-+struct scaling_ratios {
-+ struct fixed31_32 horz;
-+ struct fixed31_32 vert;
-+ struct fixed31_32 horz_c;
-+ struct fixed31_32 vert_c;
-+};
-+
-+struct rect {
-+ uint32_t x;
-+ uint32_t y;
-+ uint32_t width;
-+ uint32_t height;
-+};
-+
-+struct view {
-+ uint32_t width;
-+ uint32_t height;
-+};
-+
-+struct dc_resolution {
-+ uint32_t width;
-+ uint32_t height;
-+};
-+
-+
-+struct dc_mode_flags {
-+ /* note: part of refresh rate flag*/
-+ uint32_t INTERLACE :1;
-+ /* native display timing*/
-+ uint32_t NATIVE :1;
-+ /* preferred is the recommended mode, one per display */
-+ uint32_t PREFERRED :1;
-+ /* true if this mode should use reduced blanking timings
-+ *_not_ related to the Reduced Blanking adjustment*/
-+ uint32_t REDUCED_BLANKING :1;
-+ /* note: part of refreshrate flag*/
-+ uint32_t VIDEO_OPTIMIZED_RATE :1;
-+ /* should be reported to upper layers as mode_flags*/
-+ uint32_t PACKED_PIXEL_FORMAT :1;
-+ /*< preferred view*/
-+ uint32_t PREFERRED_VIEW :1;
-+ /* this timing should be used only in tiled mode*/
-+ uint32_t TILED_MODE :1;
-+ uint32_t DSE_MODE :1;
-+ /* Refresh rate divider when Miracast sink is using a
-+ different rate than the output display device
-+ Must be zero for wired displays and non-zero for
-+ Miracast displays*/
-+ uint32_t MIRACAST_REFRESH_DIVIDER;
-+};
-+
-+struct dc_crtc_timing_flags {
-+ uint32_t INTERLACE :1;
-+ uint32_t HSYNC_POSITIVE_POLARITY :1; /* when set to 1,
-+ it is positive polarity --reversed with dal1 or video bios define*/
-+ uint32_t VSYNC_POSITIVE_POLARITY :1; /* when set to 1,
-+ it is positive polarity --reversed with dal1 or video bios define*/
-+
-+ uint32_t HORZ_COUNT_BY_TWO:1;
-+
-+ uint32_t EXCLUSIVE_3D :1; /* if this bit set,
-+ timing can be driven in 3D format only
-+ and there is no corresponding 2D timing*/
-+ uint32_t RIGHT_EYE_3D_POLARITY :1; /* 1 - means right eye polarity
-+ (right eye = '1', left eye = '0') */
-+ uint32_t SUB_SAMPLE_3D :1; /* 1 - means left/right images subsampled
-+ when mixed into 3D image. 0 - means summation (3D timing is doubled)*/
-+ uint32_t USE_IN_3D_VIEW_ONLY :1; /* Do not use this timing in 2D View,
-+ because corresponding 2D timing also present in the list*/
-+ uint32_t STEREO_3D_PREFERENCE :1; /* Means this is 2D timing
-+ and we want to match priority of corresponding 3D timing*/
-+ uint32_t Y_ONLY :1;
-+
-+ uint32_t YCBCR420 :1; /* TODO: shouldn't need this flag, should be a separate pixel format */
-+ uint32_t DTD_COUNTER :5; /* values 1 to 16 */
-+
-+ /* HDMI 2.0 - Support scrambling for TMDS character
-+ * rates less than or equal to 340Mcsc */
-+ uint32_t LTE_340MCSC_SCRAMBLE:1;
-+
-+};
-+
-+enum dc_timing_standard {
-+ TIMING_STANDARD_UNDEFINED,
-+ TIMING_STANDARD_DMT,
-+ TIMING_STANDARD_GTF,
-+ TIMING_STANDARD_CVT,
-+ TIMING_STANDARD_CVT_RB,
-+ TIMING_STANDARD_CEA770,
-+ TIMING_STANDARD_CEA861,
-+ TIMING_STANDARD_HDMI,
-+ TIMING_STANDARD_TV_NTSC,
-+ TIMING_STANDARD_TV_NTSC_J,
-+ TIMING_STANDARD_TV_PAL,
-+ TIMING_STANDARD_TV_PAL_M,
-+ TIMING_STANDARD_TV_PAL_CN,
-+ TIMING_STANDARD_TV_SECAM,
-+ TIMING_STANDARD_EXPLICIT,
-+ /*!< For explicit timings from EDID, VBIOS, etc.*/
-+ TIMING_STANDARD_USER_OVERRIDE,
-+ /*!< For mode timing override by user*/
-+ TIMING_STANDARD_MAX
-+};
-+
-+enum dc_aspect_ratio {
-+ ASPECT_RATIO_NO_DATA,
-+ ASPECT_RATIO_4_3,
-+ ASPECT_RATIO_16_9,
-+ ASPECT_RATIO_64_27,
-+ ASPECT_RATIO_256_135,
-+ ASPECT_RATIO_FUTURE
-+};
-+
-+enum dc_color_depth {
-+ COLOR_DEPTH_UNDEFINED,
-+ COLOR_DEPTH_666,
-+ COLOR_DEPTH_888,
-+ COLOR_DEPTH_101010,
-+ COLOR_DEPTH_121212,
-+ COLOR_DEPTH_141414,
-+ COLOR_DEPTH_161616,
-+ COLOR_DEPTH_COUNT
-+};
-+
-+enum dc_timing_3d_format {
-+ TIMING_3D_FORMAT_NONE,
-+ TIMING_3D_FORMAT_FRAME_ALTERNATE, /* No stereosync at all*/
-+ TIMING_3D_FORMAT_INBAND_FA, /* Inband Frame Alternate (DVI/DP)*/
-+ TIMING_3D_FORMAT_DP_HDMI_INBAND_FA, /* Inband FA to HDMI Frame Pack*/
-+ /* for active DP-HDMI dongle*/
-+ TIMING_3D_FORMAT_SIDEBAND_FA, /* Sideband Frame Alternate (eDP)*/
-+ TIMING_3D_FORMAT_HW_FRAME_PACKING,
-+ TIMING_3D_FORMAT_SW_FRAME_PACKING,
-+ TIMING_3D_FORMAT_ROW_INTERLEAVE,
-+ TIMING_3D_FORMAT_COLUMN_INTERLEAVE,
-+ TIMING_3D_FORMAT_PIXEL_INTERLEAVE,
-+ TIMING_3D_FORMAT_SIDE_BY_SIDE,
-+ TIMING_3D_FORMAT_TOP_AND_BOTTOM,
-+ TIMING_3D_FORMAT_SBS_SW_PACKED,
-+ /* Side-by-side, packed by application/driver into 2D frame*/
-+ TIMING_3D_FORMAT_TB_SW_PACKED,
-+ /* Top-and-bottom, packed by application/driver into 2D frame*/
-+
-+ TIMING_3D_FORMAT_MAX,
-+};
-+
-+enum dc_timing_source {
-+ TIMING_SOURCE_UNDEFINED,
-+
-+ /* explicitly specifed by user, most important*/
-+ TIMING_SOURCE_USER_FORCED,
-+ TIMING_SOURCE_USER_OVERRIDE,
-+ TIMING_SOURCE_CUSTOM,
-+ TIMING_SOURCE_EXPLICIT,
-+
-+ /* explicitly specified by the display device, more important*/
-+ TIMING_SOURCE_EDID_CEA_SVD_3D,
-+ TIMING_SOURCE_EDID_CEA_SVD_PREFERRED,
-+ TIMING_SOURCE_EDID_CEA_SVD_420,
-+ TIMING_SOURCE_EDID_DETAILED,
-+ TIMING_SOURCE_EDID_ESTABLISHED,
-+ TIMING_SOURCE_EDID_STANDARD,
-+ TIMING_SOURCE_EDID_CEA_SVD,
-+ TIMING_SOURCE_EDID_CVT_3BYTE,
-+ TIMING_SOURCE_EDID_4BYTE,
-+ TIMING_SOURCE_VBIOS,
-+ TIMING_SOURCE_CV,
-+ TIMING_SOURCE_TV,
-+ TIMING_SOURCE_HDMI_VIC,
-+
-+ /* implicitly specified by display device, still safe but less important*/
-+ TIMING_SOURCE_DEFAULT,
-+
-+ /* only used for custom base modes */
-+ TIMING_SOURCE_CUSTOM_BASE,
-+
-+ /* these timing might not work, least important*/
-+ TIMING_SOURCE_RANGELIMIT,
-+ TIMING_SOURCE_OS_FORCED,
-+ TIMING_SOURCE_IMPLICIT,
-+
-+ /* only used by default mode list*/
-+ TIMING_SOURCE_BASICMODE,
-+
-+ TIMING_SOURCE_COUNT
-+};
-+
-+enum dc_timing_support_method {
-+ TIMING_SUPPORT_METHOD_UNDEFINED,
-+ TIMING_SUPPORT_METHOD_EXPLICIT,
-+ TIMING_SUPPORT_METHOD_IMPLICIT,
-+ TIMING_SUPPORT_METHOD_NATIVE
-+};
-+
-+struct dc_mode_info {
-+ uint32_t pixel_width;
-+ uint32_t pixel_height;
-+ uint32_t field_rate;
-+ /* Vertical refresh rate for progressive modes.
-+ * Field rate for interlaced modes.*/
-+
-+ enum dc_timing_standard timing_standard;
-+ enum dc_timing_source timing_source;
-+ struct dc_mode_flags flags;
-+};
-+
-+/* TODO: assess necessity*/
-+/*scanning type*/
-+enum scanning_type {
-+ SCANNING_TYPE_NODATA = 0,
-+ SCANNING_TYPE_OVERSCAN,
-+ SCANNING_TYPE_UNDERSCAN,
-+ SCANNING_TYPE_FUTURE,
-+ SCANNING_TYPE_UNDEFINED
-+};
-+
-+struct dc_crtc_timing {
-+ uint32_t h_total;
-+ uint32_t h_border_left;
-+ uint32_t h_addressable;
-+ uint32_t h_border_right;
-+ uint32_t h_front_porch;
-+ uint32_t h_sync_width;
-+
-+ uint32_t v_total;
-+ uint32_t v_border_top;
-+ uint32_t v_addressable;
-+ uint32_t v_border_bottom;
-+ uint32_t v_front_porch;
-+ uint32_t v_sync_width;
-+
-+ uint32_t pix_clk_khz;
-+
-+ uint32_t vic;
-+ uint32_t hdmi_vic;
-+ enum dc_timing_standard timing_standard;
-+ enum dc_timing_3d_format timing_3d_format;
-+ enum dc_color_depth display_color_depth;
-+ enum dc_pixel_encoding pixel_encoding;
-+ enum dc_aspect_ratio aspect_ratio;
-+ enum scanning_type scan_type;
-+
-+ struct dc_crtc_timing_flags flags;
-+};
-+
-+struct dc_mode_timing {
-+ struct dc_mode_info mode_info;
-+ struct dc_crtc_timing crtc_timing;
-+};
-+
-+/* Rotation angle */
-+enum dc_rotation_angle {
-+ ROTATION_ANGLE_0 = 0,
-+ ROTATION_ANGLE_90,
-+ ROTATION_ANGLE_180,
-+ ROTATION_ANGLE_270,
-+ ROTATION_ANGLE_COUNT
-+};
-+
-+struct dc_cursor_position {
-+ uint32_t x;
-+ uint32_t y;
-+
-+ uint32_t x_origin;
-+ uint32_t y_origin;
-+
-+ /*
-+ * This parameter indicates whether HW cursor should be enabled
-+ */
-+ bool enable;
-+
-+ /*
-+ * This parameter indicates whether cursor hot spot should be
-+ * programmed
-+ */
-+ bool hot_spot_enable;
-+};
-+
-+/* This enum is for programming CURSOR_MODE register field. */
-+/* What this register should be programmed to depends on */
-+/* OS requested cursor shape flags */
-+/* and what we stored in the cursor surface. */
-+enum dc_cursor_color_format {
-+ CURSOR_MODE_MONO,
-+ CURSOR_MODE_COLOR_1BIT_AND,
-+ CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA,
-+ CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA
-+};
-+
-+union dc_cursor_attribute_flags {
-+ struct {
-+ uint32_t ENABLE_MAGNIFICATION:1;
-+ uint32_t INVERSE_TRANSPARENT_CLAMPING:1;
-+ uint32_t HORIZONTAL_MIRROR:1;
-+ uint32_t VERTICAL_MIRROR:1;
-+ uint32_t RESERVED:28;
-+ } bits;
-+ uint32_t value;
-+};
-+
-+/* This is all the parameters required by DAL in order to */
-+/* update the cursor attributes, */
-+/* including the new cursor image surface address, size, */
-+/* hotspot location, color format, etc. */
-+struct dc_cursor_attributes {
-+ PHYSICAL_ADDRESS_LOC address;
-+
-+ /* Width and height should correspond to cursor surface width x heigh */
-+ uint32_t width;
-+ uint32_t height;
-+ uint32_t x_hot;
-+ uint32_t y_hot;
-+
-+ enum dc_cursor_color_format color_format;
-+
-+ /* In case we support HW Cursor rotation in the future */
-+ enum dc_rotation_angle rotation_angle;
-+
-+ union dc_cursor_attribute_flags attribute_flags;
-+
-+};
-+
-+
-+enum dc_plane_addr_type {
-+ PLN_ADDR_TYPE_GRAPHICS = 0,
-+ PLN_ADDR_TYPE_GRPH_STEREO,
-+ PLN_ADDR_TYPE_VIDEO_PROGRESSIVE,
-+ PLN_ADDR_TYPE_VIDEO_INTERLACED,
-+ PLN_ADDR_TYPE_VIDEO_PROGRESSIVE_STEREO,
-+ PLN_ADDR_TYPE_VIDEO_INTERLACED_STEREO
-+};
-+
-+struct dc_plane_address {
-+ enum dc_plane_addr_type type;
-+ union {
-+ struct{
-+ PHYSICAL_ADDRESS_LOC addr;
-+ } grph;
-+
-+ /*stereo*/
-+ struct {
-+ PHYSICAL_ADDRESS_LOC left_addr;
-+ PHYSICAL_ADDRESS_LOC right_addr;
-+ } grph_stereo;
-+
-+ /*video progressive*/
-+ struct {
-+ PHYSICAL_ADDRESS_LOC chroma_addr;
-+ PHYSICAL_ADDRESS_LOC luma_addr;
-+ } video_progressive;
-+
-+ /*video interlaced*/
-+ struct {
-+ PHYSICAL_ADDRESS_LOC chroma_addr;
-+ PHYSICAL_ADDRESS_LOC luma_addr;
-+ PHYSICAL_ADDRESS_LOC chroma_bottom_addr;
-+ PHYSICAL_ADDRESS_LOC luma_bottom_addr;
-+ } video_interlaced;
-+
-+ /*video Progressive Stereo*/
-+ struct {
-+ PHYSICAL_ADDRESS_LOC left_chroma_addr;
-+ PHYSICAL_ADDRESS_LOC left_luma_addr;
-+ PHYSICAL_ADDRESS_LOC right_chroma_addr;
-+ PHYSICAL_ADDRESS_LOC right_luma_addr;
-+ } video_progressive_stereo;
-+
-+ /*video interlaced stereo*/
-+ struct {
-+ PHYSICAL_ADDRESS_LOC left_chroma_addr;
-+ PHYSICAL_ADDRESS_LOC left_luma_addr;
-+ PHYSICAL_ADDRESS_LOC left_chroma_bottom_addr;
-+ PHYSICAL_ADDRESS_LOC left_luma_bottom_addr;
-+
-+ PHYSICAL_ADDRESS_LOC right_chroma_addr;
-+ PHYSICAL_ADDRESS_LOC right_luma_addr;
-+ PHYSICAL_ADDRESS_LOC right_chroma_bottom_addr;
-+ PHYSICAL_ADDRESS_LOC right_luma_bottom_addr;
-+ } video_interlaced_stereo;
-+ };
-+};
-+
-+enum dc_power_state {
-+ DC_POWER_STATE_ON = 1,
-+ DC_POWER_STATE_STANDBY,
-+ DC_POWER_STATE_SUSPEND,
-+ DC_POWER_STATE_OFF
-+};
-+
-+/* DC PowerStates */
-+enum dc_video_power_state {
-+ DC_VIDEO_POWER_UNSPECIFIED = 0,
-+ DC_VIDEO_POWER_ON = 1,
-+ DC_VIDEO_POWER_STANDBY,
-+ DC_VIDEO_POWER_SUSPEND,
-+ DC_VIDEO_POWER_OFF,
-+ DC_VIDEO_POWER_HIBERNATE,
-+ DC_VIDEO_POWER_SHUTDOWN,
-+ DC_VIDEO_POWER_ULPS, /* BACO or Ultra-Light-Power-State */
-+ DC_VIDEO_POWER_AFTER_RESET,
-+ DC_VIDEO_POWER_MAXIMUM
-+};
-+
-+enum dc_acpi_cm_power_state {
-+ DC_ACPI_CM_POWER_STATE_D0 = 1,
-+ DC_ACPI_CM_POWER_STATE_D1 = 2,
-+ DC_ACPI_CM_POWER_STATE_D2 = 4,
-+ DC_ACPI_CM_POWER_STATE_D3 = 8
-+};
-+
-+struct view_port_alignment {
-+ uint8_t x_width_size_alignment;
-+ uint8_t y_height_size_alignment;
-+ uint8_t x_start_alignment;
-+ uint8_t y_start_alignment;
-+};
-+
-+enum dc_connection_type {
-+ dc_connection_none,
-+ dc_connection_single,
-+ dc_connection_mst_branch,
-+ dc_connection_active_dongle
-+};
-+
-+struct dc_csc_adjustments {
-+ struct fixed31_32 contrast;
-+ struct fixed31_32 saturation;
-+ struct fixed31_32 brightness;
-+ struct fixed31_32 hue;
-+};
-+
-+#include "dc_temp.h"
-+
-+#endif /* DC_TYPES_H_ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/Makefile b/drivers/gpu/drm/amd/dal/dc/dce110/Makefile
-new file mode 100644
-index 0000000..5bf9b56
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/Makefile
-@@ -0,0 +1,33 @@
-+#
-+# Makefile for the 'controller' sub-component of DAL.
-+# It provides the control and status of HW CRTC block.
-+
-+DCE110 = dce110_ipp.o dce110_ipp_cursor.o \
-+dce110_ipp_gamma.o dce110_link_encoder.o dce110_opp.o \
-+dce110_opp_formatter.o dce110_opp_regamma.o dce110_stream_encoder.o \
-+dce110_timing_generator.o dce110_transform.o dce110_transform_gamut.o \
-+dce110_transform_scl.o dce110_transform_sclv.o dce110_opp_csc.o\
-+dce110_compressor.o dce110_mem_input.o dce110_hw_sequencer.o \
-+dce110_resource.o dce110_transform_bit_depth.o
-+
-+AMD_DAL_DCE110 = $(addprefix $(AMDDALPATH)/dc/dce110/,$(DCE110))
-+
-+AMD_DAL_FILES += $(AMD_DAL_DCE110)
-+
-+
-+###############################################################################
-+# DCE 11x
-+###############################################################################
-+ifdef 0#CONFIG_DRM_AMD_DAL_DCE11_0
-+TG_DCE110 = dce110_ipp.o dce110_ipp_cursor.o \
-+dce110_ipp_gamma.o dce110_timing_generator.o dce110_link_encoder.o \
-+dce110_opp.o dce110_opp_regamma.o dce110_opp_formatter.o dce110_opp_csc.o \
-+dce110_transform.o dce110_transform_gamut.o dce110_transform_bit_depth.o \
-+dce110_compressor.o dce110_mem_input.o dce110_hw_sequencer.o dce110_resource.o
-+
-+AMD_DAL_TG_DCE110 = $(addprefix \
-+ $(AMDDALPATH)/dc/dce110/,$(TG_DCE110))
-+
-+AMD_DAL_FILES += $(AMD_DAL_TG_DCE110)
-+endif
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_compressor.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_compressor.c
-new file mode 100644
-index 0000000..7abb790
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_compressor.c
-@@ -0,0 +1,886 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+#include "gmc/gmc_8_2_sh_mask.h"
-+#include "gmc/gmc_8_2_d.h"
-+
-+#include "include/logger_interface.h"
-+#include "include/adapter_service_interface.h"
-+
-+#include "dce110_compressor.h"
-+
-+#define DCP_REG(reg)\
-+ (reg + cp110->offsets.dcp_offset)
-+#define DMIF_REG(reg)\
-+ (reg + cp110->offsets.dmif_offset)
-+
-+static const struct dce110_compressor_reg_offsets reg_offsets[] = {
-+{
-+ .dcp_offset = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif_offset =
-+ (mmDMIF_PG0_DPG_PIPE_DPM_CONTROL
-+ - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif_offset =
-+ (mmDMIF_PG1_DPG_PIPE_DPM_CONTROL
-+ - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif_offset =
-+ (mmDMIF_PG2_DPG_PIPE_DPM_CONTROL
-+ - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-+}
-+};
-+
-+static const uint32_t dce11_one_lpt_channel_max_resolution = 2560 * 1600;
-+
-+enum fbc_idle_force {
-+ /* Bit 0 - Display registers updated */
-+ FBC_IDLE_FORCE_DISPLAY_REGISTER_UPDATE = 0x00000001,
-+
-+ /* Bit 2 - FBC_GRPH_COMP_EN register updated */
-+ FBC_IDLE_FORCE_GRPH_COMP_EN = 0x00000002,
-+ /* Bit 3 - FBC_SRC_SEL register updated */
-+ FBC_IDLE_FORCE_SRC_SEL_CHANGE = 0x00000004,
-+ /* Bit 4 - FBC_MIN_COMPRESSION register updated */
-+ FBC_IDLE_FORCE_MIN_COMPRESSION_CHANGE = 0x00000008,
-+ /* Bit 5 - FBC_ALPHA_COMP_EN register updated */
-+ FBC_IDLE_FORCE_ALPHA_COMP_EN = 0x00000010,
-+ /* Bit 6 - FBC_ZERO_ALPHA_CHUNK_SKIP_EN register updated */
-+ FBC_IDLE_FORCE_ZERO_ALPHA_CHUNK_SKIP_EN = 0x00000020,
-+ /* Bit 7 - FBC_FORCE_COPY_TO_COMP_BUF register updated */
-+ FBC_IDLE_FORCE_FORCE_COPY_TO_COMP_BUF = 0x00000040,
-+
-+ /* Bit 24 - Memory write to region 0 defined by MC registers. */
-+ FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION0 = 0x01000000,
-+ /* Bit 25 - Memory write to region 1 defined by MC registers */
-+ FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION1 = 0x02000000,
-+ /* Bit 26 - Memory write to region 2 defined by MC registers */
-+ FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION2 = 0x04000000,
-+ /* Bit 27 - Memory write to region 3 defined by MC registers. */
-+ FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION3 = 0x08000000,
-+
-+ /* Bit 28 - Memory write from any client other than MCIF */
-+ FBC_IDLE_FORCE_MEMORY_WRITE_OTHER_THAN_MCIF = 0x10000000,
-+ /* Bit 29 - CG statics screen signal is inactive */
-+ FBC_IDLE_FORCE_CG_STATIC_SCREEN_IS_INACTIVE = 0x20000000,
-+};
-+
-+static uint32_t lpt_size_alignment(struct dce110_compressor *cp110)
-+{
-+ /*LPT_ALIGNMENT (in bytes) = ROW_SIZE * #BANKS * # DRAM CHANNELS. */
-+ return cp110->base.raw_size * cp110->base.banks_num *
-+ cp110->base.dram_channels_num;
-+}
-+
-+static uint32_t lpt_memory_control_config(struct dce110_compressor *cp110,
-+ uint32_t lpt_control)
-+{
-+ /*LPT MC Config */
-+ if (cp110->base.options.bits.LPT_MC_CONFIG == 1) {
-+ /* POSSIBLE VALUES for LPT NUM_PIPES (DRAM CHANNELS):
-+ * 00 - 1 CHANNEL
-+ * 01 - 2 CHANNELS
-+ * 02 - 4 OR 6 CHANNELS
-+ * (Only for discrete GPU, N/A for CZ)
-+ * 03 - 8 OR 12 CHANNELS
-+ * (Only for discrete GPU, N/A for CZ) */
-+ switch (cp110->base.dram_channels_num) {
-+ case 2:
-+ set_reg_field_value(
-+ lpt_control,
-+ 1,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_NUM_PIPES);
-+ break;
-+ case 1:
-+ set_reg_field_value(
-+ lpt_control,
-+ 0,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_NUM_PIPES);
-+ break;
-+ default:
-+ dal_logger_write(
-+ cp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: Invalid LPT NUM_PIPES!!!",
-+ __func__);
-+ break;
-+ }
-+
-+ /* The mapping for LPT NUM_BANKS is in
-+ * GRPH_CONTROL.GRPH_NUM_BANKS register field
-+ * Specifies the number of memory banks for tiling
-+ * purposes. Only applies to 2D and 3D tiling modes.
-+ * POSSIBLE VALUES:
-+ * 00 - DCP_GRPH_NUM_BANKS_2BANK: ADDR_SURF_2_BANK
-+ * 01 - DCP_GRPH_NUM_BANKS_4BANK: ADDR_SURF_4_BANK
-+ * 02 - DCP_GRPH_NUM_BANKS_8BANK: ADDR_SURF_8_BANK
-+ * 03 - DCP_GRPH_NUM_BANKS_16BANK: ADDR_SURF_16_BANK */
-+ switch (cp110->base.banks_num) {
-+ case 16:
-+ set_reg_field_value(
-+ lpt_control,
-+ 3,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_NUM_BANKS);
-+ break;
-+ case 8:
-+ set_reg_field_value(
-+ lpt_control,
-+ 2,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_NUM_BANKS);
-+ break;
-+ case 4:
-+ set_reg_field_value(
-+ lpt_control,
-+ 1,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_NUM_BANKS);
-+ break;
-+ case 2:
-+ set_reg_field_value(
-+ lpt_control,
-+ 0,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_NUM_BANKS);
-+ break;
-+ default:
-+ dal_logger_write(
-+ cp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: Invalid LPT NUM_BANKS!!!",
-+ __func__);
-+ break;
-+ }
-+
-+ /* The mapping is in DMIF_ADDR_CALC.
-+ * ADDR_CONFIG_PIPE_INTERLEAVE_SIZE register field for
-+ * Carrizo specifies the memory interleave per pipe.
-+ * It effectively specifies the location of pipe bits in
-+ * the memory address.
-+ * POSSIBLE VALUES:
-+ * 00 - ADDR_CONFIG_PIPE_INTERLEAVE_256B: 256 byte
-+ * interleave
-+ * 01 - ADDR_CONFIG_PIPE_INTERLEAVE_512B: 512 byte
-+ * interleave
-+ */
-+ switch (cp110->base.channel_interleave_size) {
-+ case 256: /*256B */
-+ set_reg_field_value(
-+ lpt_control,
-+ 0,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_PIPE_INTERLEAVE_SIZE);
-+ break;
-+ case 512: /*512B */
-+ set_reg_field_value(
-+ lpt_control,
-+ 1,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_PIPE_INTERLEAVE_SIZE);
-+ break;
-+ default:
-+ dal_logger_write(
-+ cp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: Invalid LPT INTERLEAVE_SIZE!!!",
-+ __func__);
-+ break;
-+ }
-+
-+ /* The mapping for LOW_POWER_TILING_ROW_SIZE is in
-+ * DMIF_ADDR_CALC.ADDR_CONFIG_ROW_SIZE register field
-+ * for Carrizo. Specifies the size of dram row in bytes.
-+ * This should match up with NOOFCOLS field in
-+ * MC_ARB_RAMCFG (ROW_SIZE = 4 * 2 ^^ columns).
-+ * This register DMIF_ADDR_CALC is not used by the
-+ * hardware as it is only used for addrlib assertions.
-+ * POSSIBLE VALUES:
-+ * 00 - ADDR_CONFIG_1KB_ROW: Treat 1KB as DRAM row
-+ * boundary
-+ * 01 - ADDR_CONFIG_2KB_ROW: Treat 2KB as DRAM row
-+ * boundary
-+ * 02 - ADDR_CONFIG_4KB_ROW: Treat 4KB as DRAM row
-+ * boundary */
-+ switch (cp110->base.raw_size) {
-+ case 4096: /*4 KB */
-+ set_reg_field_value(
-+ lpt_control,
-+ 2,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ROW_SIZE);
-+ break;
-+ case 2048:
-+ set_reg_field_value(
-+ lpt_control,
-+ 1,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ROW_SIZE);
-+ break;
-+ case 1024:
-+ set_reg_field_value(
-+ lpt_control,
-+ 0,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ROW_SIZE);
-+ break;
-+ default:
-+ dal_logger_write(
-+ cp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: Invalid LPT ROW_SIZE!!!",
-+ __func__);
-+ break;
-+ }
-+ } else {
-+ dal_logger_write(
-+ cp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: LPT MC Configuration is not provided",
-+ __func__);
-+ }
-+
-+ return lpt_control;
-+}
-+
-+
-+
-+static bool is_source_bigger_than_epanel_size(
-+ struct dce110_compressor *cp110,
-+ uint32_t source_view_width,
-+ uint32_t source_view_height)
-+{
-+ if (cp110->base.embedded_panel_h_size != 0 &&
-+ cp110->base.embedded_panel_v_size != 0 &&
-+ ((source_view_width * source_view_height) >
-+ (cp110->base.embedded_panel_h_size *
-+ cp110->base.embedded_panel_v_size)))
-+ return true;
-+
-+ return false;
-+}
-+
-+static uint32_t align_to_chunks_number_per_line(
-+ struct dce110_compressor *cp110,
-+ uint32_t pixels)
-+{
-+ return 256 * ((pixels + 255) / 256);
-+}
-+
-+static void wait_for_fbc_state_changed(
-+ struct dce110_compressor *cp110,
-+ bool enabled)
-+{
-+ uint8_t counter = 0;
-+ uint32_t addr = mmFBC_STATUS;
-+ uint32_t value;
-+
-+ while (counter < 10) {
-+ value = dal_read_reg(cp110->base.ctx, addr);
-+ if (get_reg_field_value(
-+ value,
-+ FBC_STATUS,
-+ FBC_ENABLE_STATUS) == enabled)
-+ break;
-+ dc_service_delay_in_microseconds(cp110->base.ctx, 10);
-+ counter++;
-+ }
-+
-+ if (counter == 10) {
-+ dal_logger_write(
-+ cp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: wait counter exceeded, changes to HW not applied",
-+ __func__);
-+ }
-+}
-+
-+void dce110_compressor_power_up_fbc(struct compressor *compressor)
-+{
-+ uint32_t value;
-+ uint32_t addr;
-+
-+ addr = mmFBC_CNTL;
-+ value = dal_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(value, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
-+ set_reg_field_value(value, 1, FBC_CNTL, FBC_EN);
-+ set_reg_field_value(value, 2, FBC_CNTL, FBC_COHERENCY_MODE);
-+ if (compressor->options.bits.CLK_GATING_DISABLED == 1) {
-+ /* HW needs to do power measurement comparison. */
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ FBC_CNTL,
-+ FBC_COMP_CLK_GATE_EN);
-+ }
-+ dal_write_reg(compressor->ctx, addr, value);
-+
-+ addr = mmFBC_COMP_MODE;
-+ value = dal_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(value, 1, FBC_COMP_MODE, FBC_RLE_EN);
-+ set_reg_field_value(value, 1, FBC_COMP_MODE, FBC_DPCM4_RGB_EN);
-+ set_reg_field_value(value, 1, FBC_COMP_MODE, FBC_IND_EN);
-+ dal_write_reg(compressor->ctx, addr, value);
-+
-+ addr = mmFBC_COMP_CNTL;
-+ value = dal_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(value, 1, FBC_COMP_CNTL, FBC_DEPTH_RGB08_EN);
-+ dal_write_reg(compressor->ctx, addr, value);
-+ /*FBC_MIN_COMPRESSION 0 ==> 2:1 */
-+ /* 1 ==> 4:1 */
-+ /* 2 ==> 8:1 */
-+ /* 0xF ==> 1:1 */
-+ set_reg_field_value(value, 0xF, FBC_COMP_CNTL, FBC_MIN_COMPRESSION);
-+ dal_write_reg(compressor->ctx, addr, value);
-+ compressor->min_compress_ratio = FBC_COMPRESS_RATIO_1TO1;
-+
-+ value = 0;
-+ dal_write_reg(compressor->ctx, mmFBC_IND_LUT0, value);
-+
-+ value = 0xFFFFFF;
-+ dal_write_reg(compressor->ctx, mmFBC_IND_LUT1, value);
-+}
-+
-+void dce110_compressor_enable_fbc(
-+ struct compressor *compressor,
-+ uint32_t paths_num,
-+ struct compr_addr_and_pitch_params *params)
-+{
-+ struct dce110_compressor *cp110 = TO_DCE110_COMPRESSOR(compressor);
-+
-+ if (compressor->options.bits.FBC_SUPPORT &&
-+ (compressor->options.bits.DUMMY_BACKEND == 0) &&
-+ (!dce110_compressor_is_fbc_enabled_in_hw(compressor, NULL)) &&
-+ (!is_source_bigger_than_epanel_size(
-+ cp110,
-+ params->source_view_width,
-+ params->source_view_height))) {
-+
-+ uint32_t addr;
-+ uint32_t value;
-+
-+ /* Before enabling FBC first need to enable LPT if applicable
-+ * LPT state should always be changed (enable/disable) while FBC
-+ * is disabled */
-+ if (compressor->options.bits.LPT_SUPPORT && (paths_num < 2) &&
-+ (params->source_view_width *
-+ params->source_view_height <=
-+ dce11_one_lpt_channel_max_resolution)) {
-+ dce110_compressor_enable_lpt(compressor);
-+ }
-+
-+ addr = mmFBC_CNTL;
-+ value = dal_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(value, 1, FBC_CNTL, FBC_GRPH_COMP_EN);
-+ set_reg_field_value(
-+ value,
-+ params->inst,
-+ FBC_CNTL, FBC_SRC_SEL);
-+ dal_write_reg(compressor->ctx, addr, value);
-+
-+ /* Keep track of enum controller_id FBC is attached to */
-+ compressor->is_enabled = true;
-+ compressor->attached_inst = params->inst;
-+ cp110->offsets = reg_offsets[params->inst - 1];
-+
-+ /*Toggle it as there is bug in HW */
-+ set_reg_field_value(value, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
-+ dal_write_reg(compressor->ctx, addr, value);
-+ set_reg_field_value(value, 1, FBC_CNTL, FBC_GRPH_COMP_EN);
-+ dal_write_reg(compressor->ctx, addr, value);
-+
-+ wait_for_fbc_state_changed(cp110, true);
-+ }
-+}
-+
-+void dce110_compressor_disable_fbc(struct compressor *compressor)
-+{
-+ struct dce110_compressor *cp110 = TO_DCE110_COMPRESSOR(compressor);
-+
-+ if (compressor->options.bits.FBC_SUPPORT &&
-+ dce110_compressor_is_fbc_enabled_in_hw(compressor, NULL)) {
-+ uint32_t reg_data;
-+ /* Turn off compression */
-+ reg_data = dal_read_reg(compressor->ctx, mmFBC_CNTL);
-+ set_reg_field_value(reg_data, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
-+ dal_write_reg(compressor->ctx, mmFBC_CNTL, reg_data);
-+
-+ /* Reset enum controller_id to undefined */
-+ compressor->attached_inst = 0;
-+ compressor->is_enabled = false;
-+
-+ /* Whenever disabling FBC make sure LPT is disabled if LPT
-+ * supported */
-+ if (compressor->options.bits.LPT_SUPPORT)
-+ dce110_compressor_disable_lpt(compressor);
-+
-+ wait_for_fbc_state_changed(cp110, false);
-+ }
-+}
-+
-+bool dce110_compressor_is_fbc_enabled_in_hw(
-+ struct compressor *compressor,
-+ uint32_t *inst)
-+{
-+ /* Check the hardware register */
-+ uint32_t value;
-+
-+ value = dal_read_reg(compressor->ctx, mmFBC_STATUS);
-+ if (get_reg_field_value(value, FBC_STATUS, FBC_ENABLE_STATUS)) {
-+ if (inst != NULL)
-+ *inst = compressor->attached_inst;
-+ return true;
-+ }
-+
-+ value = dal_read_reg(compressor->ctx, mmFBC_MISC);
-+ if (get_reg_field_value(value, FBC_MISC, FBC_STOP_ON_HFLIP_EVENT)) {
-+ value = dal_read_reg(compressor->ctx, mmFBC_CNTL);
-+
-+ if (get_reg_field_value(value, FBC_CNTL, FBC_GRPH_COMP_EN)) {
-+ if (inst != NULL)
-+ *inst =
-+ compressor->attached_inst;
-+ return true;
-+ }
-+ }
-+ return false;
-+}
-+
-+bool dce110_compressor_is_lpt_enabled_in_hw(struct compressor *compressor)
-+{
-+ /* Check the hardware register */
-+ uint32_t value = dal_read_reg(compressor->ctx,
-+ mmLOW_POWER_TILING_CONTROL);
-+
-+ return get_reg_field_value(
-+ value,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ENABLE);
-+}
-+
-+void dce110_compressor_program_compressed_surface_address_and_pitch(
-+ struct compressor *compressor,
-+ struct compr_addr_and_pitch_params *params)
-+{
-+ struct dce110_compressor *cp110 = TO_DCE110_COMPRESSOR(compressor);
-+ uint32_t value = 0;
-+ uint32_t fbc_pitch = 0;
-+ uint32_t compressed_surf_address_low_part =
-+ compressor->compr_surface_address.addr.low_part;
-+
-+ /* Clear content first. */
-+ dal_write_reg(
-+ compressor->ctx,
-+ DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS_HIGH),
-+ 0);
-+ dal_write_reg(compressor->ctx,
-+ DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS), 0);
-+
-+ if (compressor->options.bits.LPT_SUPPORT) {
-+ uint32_t lpt_alignment = lpt_size_alignment(cp110);
-+
-+ if (lpt_alignment != 0) {
-+ compressed_surf_address_low_part =
-+ ((compressed_surf_address_low_part
-+ + (lpt_alignment - 1)) / lpt_alignment)
-+ * lpt_alignment;
-+ }
-+ }
-+
-+ /* Write address, HIGH has to be first. */
-+ dal_write_reg(compressor->ctx,
-+ DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS_HIGH),
-+ compressor->compr_surface_address.addr.high_part);
-+ dal_write_reg(compressor->ctx,
-+ DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS),
-+ compressed_surf_address_low_part);
-+
-+ fbc_pitch = align_to_chunks_number_per_line(
-+ cp110,
-+ params->source_view_width);
-+
-+ if (compressor->min_compress_ratio == FBC_COMPRESS_RATIO_1TO1)
-+ fbc_pitch = fbc_pitch / 8;
-+ else
-+ dal_logger_write(
-+ compressor->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: Unexpected DCE11 compression ratio",
-+ __func__);
-+
-+ /* Clear content first. */
-+ dal_write_reg(compressor->ctx, DCP_REG(mmGRPH_COMPRESS_PITCH), 0);
-+
-+ /* Write FBC Pitch. */
-+ set_reg_field_value(
-+ value,
-+ fbc_pitch,
-+ GRPH_COMPRESS_PITCH,
-+ GRPH_COMPRESS_PITCH);
-+ dal_write_reg(compressor->ctx, DCP_REG(mmGRPH_COMPRESS_PITCH), value);
-+
-+}
-+
-+void dce110_compressor_disable_lpt(struct compressor *compressor)
-+{
-+ struct dce110_compressor *cp110 = TO_DCE110_COMPRESSOR(compressor);
-+ uint32_t value;
-+ uint32_t addr;
-+ uint32_t inx;
-+
-+ /* Disable all pipes LPT Stutter */
-+ for (inx = 0; inx < 3; inx++) {
-+ value =
-+ dal_read_reg(
-+ compressor->ctx,
-+ DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH));
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DPG_PIPE_STUTTER_CONTROL_NONLPTCH,
-+ STUTTER_ENABLE_NONLPTCH);
-+ dal_write_reg(
-+ compressor->ctx,
-+ DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH),
-+ value);
-+ }
-+ /* Disable Underlay pipe LPT Stutter */
-+ addr = mmDPGV0_PIPE_STUTTER_CONTROL_NONLPTCH;
-+ value = dal_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DPGV0_PIPE_STUTTER_CONTROL_NONLPTCH,
-+ STUTTER_ENABLE_NONLPTCH);
-+ dal_write_reg(compressor->ctx, addr, value);
-+
-+ /* Disable LPT */
-+ addr = mmLOW_POWER_TILING_CONTROL;
-+ value = dal_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ENABLE);
-+ dal_write_reg(compressor->ctx, addr, value);
-+
-+ /* Clear selection of Channel(s) containing Compressed Surface */
-+ addr = mmGMCON_LPT_TARGET;
-+ value = dal_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 0xFFFFFFFF,
-+ GMCON_LPT_TARGET,
-+ STCTRL_LPT_TARGET);
-+ dal_write_reg(compressor->ctx, mmGMCON_LPT_TARGET, value);
-+}
-+
-+void dce110_compressor_enable_lpt(struct compressor *compressor)
-+{
-+ struct dce110_compressor *cp110 = TO_DCE110_COMPRESSOR(compressor);
-+ uint32_t value;
-+ uint32_t addr;
-+ uint32_t value_control;
-+ uint32_t channels;
-+
-+ /* Enable LPT Stutter from Display pipe */
-+ value = dal_read_reg(compressor->ctx,
-+ DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH));
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_STUTTER_CONTROL_NONLPTCH,
-+ STUTTER_ENABLE_NONLPTCH);
-+ dal_write_reg(compressor->ctx,
-+ DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH), value);
-+
-+ /* Enable Underlay pipe LPT Stutter */
-+ addr = mmDPGV0_PIPE_STUTTER_CONTROL_NONLPTCH;
-+ value = dal_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPGV0_PIPE_STUTTER_CONTROL_NONLPTCH,
-+ STUTTER_ENABLE_NONLPTCH);
-+ dal_write_reg(compressor->ctx, addr, value);
-+
-+ /* Selection of Channel(s) containing Compressed Surface: 0xfffffff
-+ * will disable LPT.
-+ * STCTRL_LPT_TARGETn corresponds to channel n. */
-+ addr = mmLOW_POWER_TILING_CONTROL;
-+ value_control = dal_read_reg(compressor->ctx, addr);
-+ channels = get_reg_field_value(value_control,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_MODE);
-+
-+ addr = mmGMCON_LPT_TARGET;
-+ value = dal_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ channels + 1, /* not mentioned in programming guide,
-+ but follow DCE8.1 */
-+ GMCON_LPT_TARGET,
-+ STCTRL_LPT_TARGET);
-+ dal_write_reg(compressor->ctx, addr, value);
-+
-+ /* Enable LPT */
-+ addr = mmLOW_POWER_TILING_CONTROL;
-+ value = dal_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ENABLE);
-+ dal_write_reg(compressor->ctx, addr, value);
-+}
-+
-+void dce110_compressor_program_lpt_control(
-+ struct compressor *compressor,
-+ struct compr_addr_and_pitch_params *params)
-+{
-+ struct dce110_compressor *cp110 = TO_DCE110_COMPRESSOR(compressor);
-+ uint32_t rows_per_channel;
-+ uint32_t lpt_alignment;
-+ uint32_t source_view_width;
-+ uint32_t source_view_height;
-+ uint32_t lpt_control = 0;
-+
-+ if (!compressor->options.bits.LPT_SUPPORT)
-+ return;
-+
-+ lpt_control = dal_read_reg(compressor->ctx,
-+ mmLOW_POWER_TILING_CONTROL);
-+
-+ /* POSSIBLE VALUES for Low Power Tiling Mode:
-+ * 00 - Use channel 0
-+ * 01 - Use Channel 0 and 1
-+ * 02 - Use Channel 0,1,2,3
-+ * 03 - reserved */
-+ switch (compressor->lpt_channels_num) {
-+ /* case 2:
-+ * Use Channel 0 & 1 / Not used for DCE 11 */
-+ case 1:
-+ /*Use Channel 0 for LPT for DCE 11 */
-+ set_reg_field_value(
-+ lpt_control,
-+ 0,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_MODE);
-+ break;
-+ default:
-+ dal_logger_write(
-+ compressor->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: Invalid selected DRAM channels for LPT!!!",
-+ __func__);
-+ break;
-+ }
-+
-+ lpt_control = lpt_memory_control_config(cp110, lpt_control);
-+
-+ /* Program LOW_POWER_TILING_ROWS_PER_CHAN field which depends on
-+ * FBC compressed surface pitch.
-+ * LOW_POWER_TILING_ROWS_PER_CHAN = Roundup ((Surface Height *
-+ * Surface Pitch) / (Row Size * Number of Channels *
-+ * Number of Banks)). */
-+ rows_per_channel = 0;
-+ lpt_alignment = lpt_size_alignment(cp110);
-+ source_view_width =
-+ align_to_chunks_number_per_line(
-+ cp110,
-+ params->source_view_width);
-+ source_view_height = (params->source_view_height + 1) & (~0x1);
-+
-+ if (lpt_alignment != 0) {
-+ rows_per_channel = source_view_width * source_view_height * 4;
-+ rows_per_channel =
-+ (rows_per_channel % lpt_alignment) ?
-+ (rows_per_channel / lpt_alignment + 1) :
-+ rows_per_channel / lpt_alignment;
-+ }
-+
-+ set_reg_field_value(
-+ lpt_control,
-+ rows_per_channel,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ROWS_PER_CHAN);
-+
-+ dal_write_reg(compressor->ctx,
-+ mmLOW_POWER_TILING_CONTROL, lpt_control);
-+}
-+
-+/*
-+ * DCE 11 Frame Buffer Compression Implementation
-+ */
-+
-+
-+void dce110_compressor_set_fbc_invalidation_triggers(
-+ struct compressor *compressor,
-+ uint32_t fbc_trigger)
-+{
-+ /* Disable region hit event, FBC_MEMORY_REGION_MASK = 0 (bits 16-19)
-+ * for DCE 11 regions cannot be used - does not work with S/G
-+ */
-+ uint32_t addr = mmFBC_CLIENT_REGION_MASK;
-+ uint32_t value = dal_read_reg(compressor->ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ FBC_CLIENT_REGION_MASK,
-+ FBC_MEMORY_REGION_MASK);
-+ dal_write_reg(compressor->ctx, addr, value);
-+
-+ /* Setup events when to clear all CSM entries (effectively marking
-+ * current compressed data invalid)
-+ * For DCE 11 CSM metadata 11111 means - "Not Compressed"
-+ * Used as the initial value of the metadata sent to the compressor
-+ * after invalidation, to indicate that the compressor should attempt
-+ * to compress all chunks on the current pass. Also used when the chunk
-+ * is not successfully written to memory.
-+ * When this CSM value is detected, FBC reads from the uncompressed
-+ * buffer. Set events according to passed in value, these events are
-+ * valid for DCE11:
-+ * - bit 0 - display register updated
-+ * - bit 28 - memory write from any client except from MCIF
-+ * - bit 29 - CG static screen signal is inactive
-+ * In addition, DCE11.1 also needs to set new DCE11.1 specific events
-+ * that are used to trigger invalidation on certain register changes,
-+ * for example enabling of Alpha Compression may trigger invalidation of
-+ * FBC once bit is set. These events are as follows:
-+ * - Bit 2 - FBC_GRPH_COMP_EN register updated
-+ * - Bit 3 - FBC_SRC_SEL register updated
-+ * - Bit 4 - FBC_MIN_COMPRESSION register updated
-+ * - Bit 5 - FBC_ALPHA_COMP_EN register updated
-+ * - Bit 6 - FBC_ZERO_ALPHA_CHUNK_SKIP_EN register updated
-+ * - Bit 7 - FBC_FORCE_COPY_TO_COMP_BUF register updated
-+ */
-+ addr = mmFBC_IDLE_FORCE_CLEAR_MASK;
-+ value = dal_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ fbc_trigger |
-+ FBC_IDLE_FORCE_GRPH_COMP_EN |
-+ FBC_IDLE_FORCE_SRC_SEL_CHANGE |
-+ FBC_IDLE_FORCE_MIN_COMPRESSION_CHANGE |
-+ FBC_IDLE_FORCE_ALPHA_COMP_EN |
-+ FBC_IDLE_FORCE_ZERO_ALPHA_CHUNK_SKIP_EN |
-+ FBC_IDLE_FORCE_FORCE_COPY_TO_COMP_BUF,
-+ FBC_IDLE_FORCE_CLEAR_MASK,
-+ FBC_IDLE_FORCE_CLEAR_MASK);
-+ dal_write_reg(compressor->ctx, addr, value);
-+}
-+
-+bool dce110_compressor_construct(struct dce110_compressor *compressor,
-+ struct dc_context *ctx, struct adapter_service *as)
-+{
-+ struct embedded_panel_info panel_info;
-+
-+ compressor->base.options.bits.FBC_SUPPORT = true;
-+ if (!(dal_adapter_service_is_feature_supported(
-+ FEATURE_DISABLE_LPT_SUPPORT)))
-+ compressor->base.options.bits.LPT_SUPPORT = true;
-+ /* For DCE 11 always use one DRAM channel for LPT */
-+ compressor->base.lpt_channels_num = 1;
-+
-+ if (dal_adapter_service_is_feature_supported(FEATURE_DUMMY_FBC_BACKEND))
-+ compressor->base.options.bits.DUMMY_BACKEND = true;
-+
-+ /* Check if this system has more than 1 DRAM channel; if only 1 then LPT
-+ * should not be supported */
-+ if (compressor->base.memory_bus_width == 64)
-+ compressor->base.options.bits.LPT_SUPPORT = false;
-+
-+ if (dal_adapter_service_is_feature_supported(
-+ FEATURE_DISABLE_FBC_COMP_CLK_GATE))
-+ compressor->base.options.bits.CLK_GATING_DISABLED = true;
-+
-+ compressor->base.ctx = ctx;
-+ compressor->base.embedded_panel_h_size = 0;
-+ compressor->base.embedded_panel_v_size = 0;
-+ compressor->base.memory_bus_width =
-+ dal_adapter_service_get_asic_vram_bit_width(as);
-+ compressor->base.allocated_size = 0;
-+ compressor->base.preferred_requested_size = 0;
-+ compressor->base.min_compress_ratio = FBC_COMPRESS_RATIO_INVALID;
-+ compressor->base.options.raw = 0;
-+ compressor->base.banks_num = 0;
-+ compressor->base.raw_size = 0;
-+ compressor->base.channel_interleave_size = 0;
-+ compressor->base.dram_channels_num = 0;
-+ compressor->base.lpt_channels_num = 0;
-+ compressor->base.attached_inst = 0;
-+ compressor->base.is_enabled = false;
-+
-+ if (dal_adapter_service_get_embedded_panel_info(as,
-+ &panel_info)) {
-+ compressor->base.embedded_panel_h_size =
-+ panel_info.lcd_timing.horizontal_addressable;
-+ compressor->base.embedded_panel_v_size =
-+ panel_info.lcd_timing.vertical_addressable;
-+ }
-+ return true;
-+}
-+
-+struct compressor *dce110_compressor_create(struct dc_context *ctx,
-+ struct adapter_service *as)
-+{
-+ struct dce110_compressor *cp110 =
-+ dc_service_alloc(ctx, sizeof(struct dce110_compressor));
-+
-+ if (!cp110)
-+ return NULL;
-+
-+ if (dce110_compressor_construct(cp110, ctx, as))
-+ return &cp110->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dc_service_free(ctx, cp110);
-+ return NULL;
-+}
-+
-+void dce110_compressor_destroy(struct compressor **compressor)
-+{
-+ dc_service_free((*compressor)->ctx, TO_DCE110_COMPRESSOR(*compressor));
-+ *compressor = NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_compressor.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_compressor.h
-new file mode 100644
-index 0000000..0beef22
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_compressor.h
-@@ -0,0 +1,84 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_COMPRESSOR_DCE110_H__
-+#define __DC_COMPRESSOR_DCE110_H__
-+
-+#include "../inc/compressor.h"
-+
-+#define TO_DCE110_COMPRESSOR(compressor)\
-+ container_of(compressor, struct dce110_compressor, base)
-+
-+struct dce110_compressor_reg_offsets {
-+ uint32_t dcp_offset;
-+ uint32_t dmif_offset;
-+};
-+
-+struct dce110_compressor {
-+ struct compressor base;
-+ struct dce110_compressor_reg_offsets offsets;
-+};
-+
-+struct compressor *dce110_compressor_create(struct dc_context *ctx,
-+ struct adapter_service *as);
-+
-+bool dce110_compressor_construct(struct dce110_compressor *cp110,
-+ struct dc_context *ctx, struct adapter_service *as);
-+
-+void dce110_compressor_destroy(struct compressor **cp);
-+
-+/* FBC RELATED */
-+void dce110_compressor_power_up_fbc(struct compressor *cp);
-+
-+void dce110_compressor_enable_fbc(struct compressor *cp, uint32_t paths_num,
-+ struct compr_addr_and_pitch_params *params);
-+
-+void dce110_compressor_disable_fbc(struct compressor *cp);
-+
-+void dce110_compressor_set_fbc_invalidation_triggers(struct compressor *cp,
-+ uint32_t fbc_trigger);
-+
-+void dce110_compressor_program_compressed_surface_address_and_pitch(
-+ struct compressor *cp,
-+ struct compr_addr_and_pitch_params *params);
-+
-+bool dce110_compressor_get_required_compressed_surface_size(
-+ struct compressor *cp,
-+ struct fbc_input_info *input_info,
-+ struct fbc_requested_compressed_size *size);
-+
-+bool dce110_compressor_is_fbc_enabled_in_hw(struct compressor *cp,
-+ uint32_t *fbc_mapped_crtc_id);
-+
-+/* LPT RELATED */
-+void dce110_compressor_enable_lpt(struct compressor *cp);
-+
-+void dce110_compressor_disable_lpt(struct compressor *cp);
-+
-+void dce110_compressor_program_lpt_control(struct compressor *cp,
-+ struct compr_addr_and_pitch_params *params);
-+
-+bool dce110_compressor_is_lpt_enabled_in_hw(struct compressor *cp);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c
-new file mode 100644
-index 0000000..74294cb
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c
-@@ -0,0 +1,1825 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#include "dc_services.h"
-+#include "dc.h"
-+#include "core_types.h"
-+#include "core_status.h"
-+#include "resource.h"
-+#include "hw_sequencer.h"
-+#include "dc_helpers.h"
-+
-+#include "dce110/dce110_resource.h"
-+#include "dce110/dce110_timing_generator.h"
-+#include "dce110/dce110_link_encoder.h"
-+#include "dce110/dce110_stream_encoder.h"
-+#include "stream_encoder_types.h"
-+#include "link_encoder_types.h"
-+#include "dce110/dce110_mem_input.h"
-+#include "dce110/dce110_ipp.h"
-+#include "dce110/dce110_transform.h"
-+#include "dce110/dce110_opp.h"
-+#include "gpu/dce110/dc_clock_gating_dce110.h"
-+
-+/* include DCE11 register header files */
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+struct dce110_hw_seq_reg_offsets {
-+ uint32_t dcfe_offset;
-+ uint32_t blnd_offset;
-+ uint32_t crtc_offset;
-+ uint32_t dcp_offset;
-+};
-+
-+enum crtc_stereo_mixer_mode {
-+ HW_STEREO_MIXER_MODE_INACTIVE,
-+ HW_STEREO_MIXER_MODE_ROW_INTERLEAVE,
-+ HW_STEREO_MIXER_MODE_COLUMN_INTERLEAVE,
-+ HW_STEREO_MIXER_MODE_PIXEL_INTERLEAVE,
-+ HW_STEREO_MIXER_MODE_BLENDER
-+};
-+
-+struct crtc_mixer_params {
-+ bool sub_sampling;
-+ enum crtc_stereo_mixer_mode mode;
-+};
-+
-+enum pipe_lock_control {
-+ PIPE_LOCK_CONTROL_GRAPHICS = 1 << 0,
-+ PIPE_LOCK_CONTROL_BLENDER = 1 << 1,
-+ PIPE_LOCK_CONTROL_SCL = 1 << 2,
-+ PIPE_LOCK_CONTROL_SURFACE = 1 << 3,
-+ PIPE_LOCK_CONTROL_MODE = 1 << 4
-+};
-+
-+enum blender_mode {
-+ BLENDER_MODE_CURRENT_PIPE = 0,/* Data from current pipe only */
-+ BLENDER_MODE_OTHER_PIPE, /* Data from other pipe only */
-+ BLENDER_MODE_BLENDING,/* Alpha blending - blend 'current' and 'other' */
-+ BLENDER_MODE_STEREO
-+};
-+
-+enum blender_type {
-+ BLENDER_TYPE_NON_SINGLE_PIPE = 0,
-+ BLENDER_TYPE_SB_SINGLE_PIPE,
-+ BLENDER_TYPE_TB_SINGLE_PIPE
-+};
-+
-+enum dc_memory_sleep_state {
-+ DC_MEMORY_SLEEP_DISABLE = 0,
-+ DC_MEMORY_LIGHT_SLEEP,
-+ DC_MEMORY_DEEP_SLEEP,
-+ DC_MEMORY_SHUTDOWN
-+};
-+enum {
-+ DCE110_PIPE_UPDATE_PENDING_DELAY = 1000,
-+ DCE110_PIPE_UPDATE_PENDING_CHECKCOUNT = 5000
-+};
-+
-+static const struct dce110_hw_seq_reg_offsets reg_offsets[] = {
-+{
-+ .dcfe_offset = (mmDCFE0_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .blnd_offset = (mmBLND0_BLND_CONTROL - mmBLND0_BLND_CONTROL),
-+ .crtc_offset = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-+ .dcp_offset = (mmDCP0_DVMM_PTE_CONTROL - mmDCP0_DVMM_PTE_CONTROL),
-+},
-+{
-+ .dcfe_offset = (mmDCFE1_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .blnd_offset = (mmBLND1_BLND_CONTROL - mmBLND0_BLND_CONTROL),
-+ .crtc_offset = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-+ .dcp_offset = (mmDCP1_DVMM_PTE_CONTROL - mmDCP0_DVMM_PTE_CONTROL),
-+},
-+{
-+ .dcfe_offset = (mmDCFE2_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .blnd_offset = (mmBLND2_BLND_CONTROL - mmBLND0_BLND_CONTROL),
-+ .crtc_offset = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
-+ .dcp_offset = (mmDCP2_DVMM_PTE_CONTROL - mmDCP0_DVMM_PTE_CONTROL),
-+}
-+};
-+
-+#define HW_REG_DCFE(reg, id)\
-+ (reg + reg_offsets[id].dcfe_offset)
-+
-+#define HW_REG_BLND(reg, id)\
-+ (reg + reg_offsets[id].blnd_offset)
-+
-+#define HW_REG_CRTC(reg, id)\
-+ (reg + reg_offsets[id].crtc_offset)
-+
-+#define HW_REG_DCP(reg, id)\
-+ (reg + reg_offsets[id].dcp_offset)
-+
-+
-+static void init_pte(struct dc_context *ctx);
-+
-+/*******************************************************************************
-+ * Private definitions
-+ ******************************************************************************/
-+
-+static void dce110_enable_display_pipe_clock_gating(
-+ struct dc_context *ctx,
-+ bool clock_gating)
-+{
-+ /*TODO*/
-+}
-+
-+static bool dce110_enable_display_power_gating(
-+ struct dc_context *ctx,
-+ uint8_t controller_id,
-+ struct bios_parser *bp,
-+ enum pipe_gating_control power_gating)
-+{
-+ enum bp_result bp_result = BP_RESULT_OK;
-+ enum bp_pipe_control_action cntl;
-+
-+ if (power_gating == PIPE_GATING_CONTROL_INIT)
-+ cntl = ASIC_PIPE_INIT;
-+ else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
-+ cntl = ASIC_PIPE_ENABLE;
-+ else
-+ cntl = ASIC_PIPE_DISABLE;
-+
-+ if (!(power_gating == PIPE_GATING_CONTROL_INIT &&
-+ (controller_id + 1) != CONTROLLER_ID_D0))
-+ bp_result = dal_bios_parser_enable_disp_power_gating(
-+ bp, controller_id + 1, cntl);
-+
-+ if (power_gating != PIPE_GATING_CONTROL_ENABLE)
-+ init_pte(ctx);
-+
-+ if (bp_result == BP_RESULT_OK)
-+ return true;
-+ else
-+ return false;
-+}
-+
-+
-+static bool set_gamma_ramp(
-+ struct input_pixel_processor *ipp,
-+ struct output_pixel_processor *opp,
-+ const struct gamma_ramp *ramp,
-+ const struct gamma_parameters *params)
-+{
-+ /*Power on LUT memory*/
-+ dce110_opp_power_on_regamma_lut(opp, true);
-+
-+ if (params->surface_pixel_format == PIXEL_FORMAT_INDEX8 ||
-+ params->selected_gamma_lut == GRAPHICS_GAMMA_LUT_LEGACY) {
-+ /* do legacy DCP for 256 colors if we are requested to do so */
-+ dce110_ipp_set_legacy_input_gamma_ramp(
-+ ipp, ramp, params);
-+
-+ dce110_ipp_set_legacy_input_gamma_mode(ipp, true);
-+
-+ /* set bypass */
-+ dce110_ipp_program_prescale(ipp, PIXEL_FORMAT_UNINITIALIZED);
-+
-+ dce110_ipp_set_degamma(ipp, params, true);
-+
-+ dce110_opp_set_regamma(opp, ramp, params, true);
-+ } else if (params->selected_gamma_lut ==
-+ GRAPHICS_GAMMA_LUT_LEGACY_AND_REGAMMA) {
-+ if (!dce110_opp_map_legacy_and_regamma_hw_to_x_user(
-+ opp, ramp, params)) {
-+ BREAK_TO_DEBUGGER();
-+ /* invalid parameters or bug */
-+ return false;
-+ }
-+
-+ /* do legacy DCP for 256 colors if we are requested to do so */
-+ dce110_ipp_set_legacy_input_gamma_ramp(
-+ ipp, ramp, params);
-+
-+ dce110_ipp_set_legacy_input_gamma_mode(ipp, true);
-+
-+ /* set bypass */
-+ dce110_ipp_program_prescale(ipp, PIXEL_FORMAT_UNINITIALIZED);
-+ } else {
-+ dce110_ipp_set_legacy_input_gamma_mode(ipp, false);
-+
-+ dce110_ipp_program_prescale(ipp, params->surface_pixel_format);
-+
-+ /* Do degamma step : remove the given gamma value from FB.
-+ * For FP16 or no degamma do by pass */
-+ dce110_ipp_set_degamma(ipp, params, false);
-+
-+ dce110_opp_set_regamma(opp, ramp, params, false);
-+ }
-+
-+ /*re-enable low power mode for LUT memory*/
-+ dce110_opp_power_on_regamma_lut(opp, false);
-+
-+ return true;
-+}
-+
-+static enum dc_status bios_parser_crtc_source_select(
-+ struct core_stream *stream)
-+{
-+ /* call VBIOS table to set CRTC source for the HW
-+ * encoder block
-+ * note: video bios clears all FMT setting here. */
-+
-+ struct bp_crtc_source_select crtc_source_select = {0};
-+ const struct core_sink *sink = stream->sink;
-+ crtc_source_select.engine_id = stream->stream_enc->id;
-+ crtc_source_select.controller_id = stream->controller_idx + 1;
-+ /*TODO: Need to un-hardcode color depth, dp_audio and account for
-+ * the case where signal and sink signal is different (translator
-+ * encoder)*/
-+ crtc_source_select.signal = sink->public.sink_signal;
-+ crtc_source_select.enable_dp_audio = false;
-+ crtc_source_select.sink_signal = sink->public.sink_signal;
-+ crtc_source_select.display_output_bit_depth
-+ = PANEL_8BIT_COLOR;
-+
-+ if (BP_RESULT_OK != dal_bios_parser_crtc_source_select(
-+ dal_adapter_service_get_bios_parser(sink->link->adapter_srv),
-+ &crtc_source_select)) {
-+ return DC_ERROR_UNEXPECTED;
-+ }
-+ return DC_OK;
-+}
-+
-+static enum color_space surface_color_to_color_space(
-+ struct plane_colorimetry *colorimetry)
-+{
-+ enum color_space color_space = COLOR_SPACE_UNKNOWN;
-+
-+ switch (colorimetry->color_space) {
-+ case SURFACE_COLOR_SPACE_SRGB:
-+ case SURFACE_COLOR_SPACE_XRRGB:
-+ if (colorimetry->limited_range)
-+ color_space = COLOR_SPACE_SRGB_LIMITED_RANGE;
-+ else
-+ color_space = COLOR_SPACE_SRGB_FULL_RANGE;
-+ break;
-+ case SURFACE_COLOR_SPACE_BT601:
-+ case SURFACE_COLOR_SPACE_XVYCC_BT601:
-+ color_space = COLOR_SPACE_YCBCR601;
-+ break;
-+ case SURFACE_COLOR_SPACE_BT709:
-+ case SURFACE_COLOR_SPACE_XVYCC_BT709:
-+ color_space = COLOR_SPACE_YCBCR709;
-+ break;
-+ }
-+
-+ return color_space;
-+}
-+
-+/*******************************FMT**************************************/
-+static void program_fmt(
-+ struct output_pixel_processor *opp,
-+ struct bit_depth_reduction_params *fmt_bit_depth,
-+ struct clamping_and_pixel_encoding_params *clamping)
-+{
-+ /* dithering is affected by <CrtcSourceSelect>, hence should be
-+ * programmed afterwards */
-+
-+ dce110_opp_program_bit_depth_reduction(
-+ opp,
-+ fmt_bit_depth);
-+
-+ dce110_opp_program_clamping_and_pixel_encoding(
-+ opp,
-+ clamping);
-+
-+ return;
-+}
-+
-+/***************************PIPE_CONTROL***********************************/
-+static void enable_fe_clock(
-+ struct dc_context *ctx, uint8_t controller_id, bool enable)
-+{
-+ uint32_t value = 0;
-+ uint32_t addr;
-+
-+ /*TODO: proper offset*/
-+ addr = HW_REG_DCFE(mmDCFE_CLOCK_CONTROL, controller_id);
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ enable,
-+ DCFE_CLOCK_CONTROL,
-+ DCFE_CLOCK_ENABLE);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+/*
-+static void enable_stereo_mixer(
-+ struct dc_context *ctx,
-+ const struct crtc_mixer_params *params)
-+{
-+ TODO
-+}
-+*/
-+static void disable_stereo_mixer(
-+ struct dc_context *ctx)
-+{
-+ /*TODO*/
-+}
-+
-+static void init_pte(struct dc_context *ctx)
-+{
-+ uint32_t addr;
-+ uint32_t value = 0;
-+ uint32_t chunk_int = 0;
-+ uint32_t chunk_mul = 0;
-+
-+ addr = mmUNP_DVMM_PTE_CONTROL;
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DVMM_PTE_CONTROL,
-+ DVMM_USE_SINGLE_PTE);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DVMM_PTE_CONTROL,
-+ DVMM_PTE_BUFFER_MODE0);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DVMM_PTE_CONTROL,
-+ DVMM_PTE_BUFFER_MODE1);
-+
-+ dal_write_reg(ctx, addr, value);
-+
-+ addr = mmDVMM_PTE_REQ;
-+ value = dal_read_reg(ctx, addr);
-+
-+ chunk_int = get_reg_field_value(
-+ value,
-+ DVMM_PTE_REQ,
-+ HFLIP_PTEREQ_PER_CHUNK_INT);
-+
-+ chunk_mul = get_reg_field_value(
-+ value,
-+ DVMM_PTE_REQ,
-+ HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
-+
-+ if (chunk_int != 0x4 || chunk_mul != 0x4) {
-+
-+ set_reg_field_value(
-+ value,
-+ 255,
-+ DVMM_PTE_REQ,
-+ MAX_PTEREQ_TO_ISSUE);
-+
-+ set_reg_field_value(
-+ value,
-+ 4,
-+ DVMM_PTE_REQ,
-+ HFLIP_PTEREQ_PER_CHUNK_INT);
-+
-+ set_reg_field_value(
-+ value,
-+ 4,
-+ DVMM_PTE_REQ,
-+ HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+}
-+
-+/**
-+ *****************************************************************************
-+ * Function: enable_disp_power_gating
-+ *
-+ * @brief
-+ * enable or disable power gating
-+ *
-+ * @param [in] enum pipe_gating_control power_gating true - power down,
-+ * false - power up
-+ *****************************************************************************
-+ */
-+
-+
-+/* this is a workaround for hw bug - it is a trigger on r/w */
-+
-+static void trigger_write_crtc_h_blank_start_end(
-+ struct dc_context *ctx,
-+ uint8_t controller_id)
-+{
-+ uint32_t value;
-+ uint32_t addr;
-+
-+ addr = HW_REG_CRTC(mmCRTC_H_BLANK_START_END, controller_id);
-+ value = dal_read_reg(ctx, addr);
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+static bool pipe_control_lock(
-+ struct dc_context *ctx,
-+ uint8_t controller_idx,
-+ uint32_t control_mask,
-+ bool lock)
-+{
-+ uint32_t addr = HW_REG_BLND(mmBLND_V_UPDATE_LOCK, controller_idx);
-+ uint32_t value = dal_read_reg(ctx, addr);
-+ bool need_to_wait = false;
-+
-+ if (control_mask & PIPE_LOCK_CONTROL_GRAPHICS)
-+ set_reg_field_value(
-+ value,
-+ lock,
-+ BLND_V_UPDATE_LOCK,
-+ BLND_DCP_GRPH_V_UPDATE_LOCK);
-+
-+ if (control_mask & PIPE_LOCK_CONTROL_SCL)
-+ set_reg_field_value(
-+ value,
-+ lock,
-+ BLND_V_UPDATE_LOCK,
-+ BLND_SCL_V_UPDATE_LOCK);
-+
-+ if (control_mask & PIPE_LOCK_CONTROL_SURFACE)
-+ set_reg_field_value(
-+ value,
-+ lock,
-+ BLND_V_UPDATE_LOCK,
-+ BLND_DCP_GRPH_SURF_V_UPDATE_LOCK);
-+
-+ if (control_mask & PIPE_LOCK_CONTROL_BLENDER) {
-+ set_reg_field_value(
-+ value,
-+ lock,
-+ BLND_V_UPDATE_LOCK,
-+ BLND_BLND_V_UPDATE_LOCK);
-+ need_to_wait = true;
-+ }
-+
-+ if (control_mask & PIPE_LOCK_CONTROL_MODE)
-+ set_reg_field_value(
-+ value,
-+ lock,
-+ BLND_V_UPDATE_LOCK,
-+ BLND_V_UPDATE_LOCK_MODE);
-+
-+ dal_write_reg(ctx, addr, value);
-+
-+ if (!lock && need_to_wait) {
-+ uint8_t counter = 0;
-+ const uint8_t counter_limit = 100;
-+ const uint16_t delay_us = 1000;
-+
-+ uint8_t pipe_pending;
-+
-+ addr = HW_REG_BLND(mmBLND_REG_UPDATE_STATUS,
-+ controller_idx);
-+
-+ while (counter < counter_limit) {
-+ value = dal_read_reg(ctx, addr);
-+
-+ pipe_pending = 0;
-+
-+ if (control_mask & PIPE_LOCK_CONTROL_BLENDER) {
-+ pipe_pending |=
-+ get_reg_field_value(
-+ value,
-+ BLND_REG_UPDATE_STATUS,
-+ BLND_BLNDC_UPDATE_PENDING);
-+ pipe_pending |= get_reg_field_value(
-+ value,
-+ BLND_REG_UPDATE_STATUS,
-+ BLND_BLNDO_UPDATE_PENDING);
-+ }
-+
-+ if (control_mask & PIPE_LOCK_CONTROL_SCL) {
-+ pipe_pending |=
-+ get_reg_field_value(
-+ value,
-+ BLND_REG_UPDATE_STATUS,
-+ SCL_BLNDC_UPDATE_PENDING);
-+ pipe_pending |=
-+ get_reg_field_value(
-+ value,
-+ BLND_REG_UPDATE_STATUS,
-+ SCL_BLNDO_UPDATE_PENDING);
-+ }
-+ if (control_mask & PIPE_LOCK_CONTROL_GRAPHICS) {
-+ pipe_pending |=
-+ get_reg_field_value(
-+ value,
-+ BLND_REG_UPDATE_STATUS,
-+ DCP_BLNDC_GRPH_UPDATE_PENDING);
-+ pipe_pending |=
-+ get_reg_field_value(
-+ value,
-+ BLND_REG_UPDATE_STATUS,
-+ DCP_BLNDO_GRPH_UPDATE_PENDING);
-+ }
-+ if (control_mask & PIPE_LOCK_CONTROL_SURFACE) {
-+ pipe_pending |= get_reg_field_value(
-+ value,
-+ BLND_REG_UPDATE_STATUS,
-+ DCP_BLNDC_GRPH_SURF_UPDATE_PENDING);
-+ pipe_pending |= get_reg_field_value(
-+ value,
-+ BLND_REG_UPDATE_STATUS,
-+ DCP_BLNDO_GRPH_SURF_UPDATE_PENDING);
-+ }
-+
-+ if (pipe_pending == 0)
-+ break;
-+
-+ counter++;
-+ dc_service_delay_in_microseconds(ctx, delay_us);
-+ }
-+
-+ if (counter == counter_limit) {
-+ dal_logger_write(
-+ ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: wait for update exceeded (wait %d us)\n",
-+ __func__,
-+ counter * delay_us);
-+ dal_logger_write(
-+ ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: control %d, remain value %x\n",
-+ __func__,
-+ control_mask,
-+ value);
-+ } else {
-+ /* OK. */
-+ }
-+ }
-+
-+ if (!lock && (control_mask & PIPE_LOCK_CONTROL_BLENDER))
-+ trigger_write_crtc_h_blank_start_end(ctx, controller_idx);
-+
-+ return true;
-+}
-+
-+static void set_blender_mode(
-+ struct dc_context *ctx,
-+ uint8_t controller_id,
-+ enum blender_mode mode)
-+{
-+ uint32_t value;
-+ uint32_t addr = HW_REG_BLND(mmBLND_CONTROL, controller_id);
-+ uint32_t blnd_mode;
-+ uint32_t feedthrough = 0;
-+
-+ switch (mode) {
-+ case BLENDER_MODE_OTHER_PIPE:
-+ feedthrough = 0;
-+ blnd_mode = 1;
-+ break;
-+ case BLENDER_MODE_BLENDING:
-+ feedthrough = 0;
-+ blnd_mode = 2;
-+ break;
-+ case BLENDER_MODE_CURRENT_PIPE:
-+ default:
-+ feedthrough = 1;
-+ blnd_mode = 0;
-+ break;
-+ }
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ feedthrough,
-+ BLND_CONTROL,
-+ BLND_FEEDTHROUGH_EN);
-+
-+ set_reg_field_value(
-+ value,
-+ blnd_mode,
-+ BLND_CONTROL,
-+ BLND_MODE);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+/**************************************************************************/
-+static void update_bios_scratch_critical_state(struct adapter_service *as,
-+ bool state)
-+{
-+ dal_bios_parser_set_scratch_critical_state(
-+ dal_adapter_service_get_bios_parser(as),
-+ state);
-+}
-+
-+static void update_info_frame(struct core_stream *stream)
-+{
-+ dce110_stream_encoder_update_info_packets(
-+ stream->stream_enc,
-+ stream->signal,
-+ &stream->encoder_info_frame);
-+}
-+
-+
-+static void enable_stream(struct core_stream *stream)
-+{
-+ enum lane_count lane_count = LANE_COUNT_ONE;
-+
-+ struct dc_crtc_timing *timing = &stream->public.timing;
-+ struct core_link *link = stream->sink->link;
-+
-+ /* 1. update AVI info frame (HDMI, DP)
-+ * we always need to update info frame
-+ */
-+ uint32_t active_total_with_borders;
-+ uint32_t early_control = 0;
-+ struct timing_generator *tg = stream->tg;
-+
-+ update_info_frame(stream);
-+ /* enable early control to avoid corruption on DP monitor*/
-+ active_total_with_borders =
-+ timing->h_addressable
-+ + timing->h_border_left
-+ + timing->h_border_right;
-+
-+ early_control = active_total_with_borders % lane_count;
-+
-+ if (early_control == 0)
-+ early_control = lane_count;
-+
-+ dce110_timing_generator_set_early_control(tg, early_control);
-+
-+ /* enable audio only within mode set */
-+ if (stream->audio != NULL) {
-+ dal_audio_enable_output(
-+ stream->audio,
-+ stream->stream_enc->id,
-+ stream->signal);
-+ }
-+
-+ /* For MST, there are multiply stream go to only one link.
-+ * connect DIG back_end to front_end while enable_stream and
-+ * disconnect them during disable_stream
-+ * BY this, it is logic clean to separate stream and link */
-+ dce110_link_encoder_connect_dig_be_to_fe(link->link_enc,
-+ stream->stream_enc->id, true);
-+
-+}
-+
-+static void disable_stream(struct core_stream *stream)
-+{
-+ struct core_link *link = stream->sink->link;
-+
-+ dce110_stream_encoder_stop_info_packets(
-+ stream->stream_enc,
-+ stream->stream_enc->id,
-+ stream->signal);
-+
-+ if (stream->audio) {
-+ /* mute audio */
-+ dal_audio_mute(stream->audio, stream->stream_enc->id,
-+ stream->signal);
-+
-+ /* TODO: notify audio driver for if audio modes list changed
-+ * add audio mode list change flag */
-+ /* dal_audio_disable_azalia_audio_jack_presence(stream->audio,
-+ * stream->stream_engine_id);
-+ */
-+ }
-+
-+ /* blank at encoder level */
-+ dce110_stream_encoder_blank(stream->stream_enc, stream->signal);
-+ dce110_link_encoder_connect_dig_be_to_fe(
-+ link->link_enc,
-+ stream->stream_enc->id,
-+ false);
-+
-+}
-+
-+static void unblank_stream(struct core_stream *stream,
-+ struct link_settings *link_settings)
-+{
-+ struct encoder_unblank_param params = { { 0 } };
-+
-+ /* only 3 items below are used by unblank */
-+ params.crtc_timing.pixel_clock =
-+ stream->public.timing.pix_clk_khz;
-+ params.link_settings.link_rate = link_settings->link_rate;
-+ params.signal = stream->signal;
-+ dce110_stream_encoder_unblank(
-+ stream->stream_enc, &params);
-+}
-+
-+static enum color_space get_output_color_space(
-+ const struct dc_crtc_timing *dc_crtc_timing)
-+{
-+ enum color_space color_space = COLOR_SPACE_SRGB_FULL_RANGE;
-+
-+ switch (dc_crtc_timing->pixel_encoding) {
-+ case PIXEL_ENCODING_YCBCR422:
-+ case PIXEL_ENCODING_YCBCR444:
-+ case PIXEL_ENCODING_YCBCR420:
-+ {
-+ if ((dc_crtc_timing->timing_standard ==
-+ TIMING_STANDARD_CEA770) ||
-+ (dc_crtc_timing->timing_standard ==
-+ TIMING_STANDARD_CEA861)) {
-+ if (dc_crtc_timing->pix_clk_khz > 27030) {
-+ if (dc_crtc_timing->flags.Y_ONLY)
-+ color_space =
-+ COLOR_SPACE_YCBCR709_YONLY;
-+ else
-+ color_space = COLOR_SPACE_YCBCR709;
-+ } else {
-+ if (dc_crtc_timing->flags.Y_ONLY)
-+ color_space =
-+ COLOR_SPACE_YCBCR601_YONLY;
-+ else
-+ color_space = COLOR_SPACE_YCBCR601;
-+ }
-+ }
-+ }
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ return color_space;
-+}
-+
-+static enum dc_status allocate_mst_payload(struct core_stream *stream)
-+{
-+ struct link_encoder *link_encoder = stream->sink->link->link_enc;
-+ struct stream_encoder *stream_encoder = stream->stream_enc;
-+ struct dp_mst_stream_allocation_table table;
-+ struct fixed31_32 avg_time_slots_per_mtp;
-+
-+ /* TODO: remove hardcode */
-+ table.stream_count = 1;
-+ table.stream_allocations[0].engine = stream_encoder->id;
-+
-+ dc_helpers_dp_mst_write_payload_allocation_table(
-+ stream->ctx,
-+ &stream->sink->public,
-+ &table.stream_allocations[0],
-+ true);
-+
-+ dce110_link_encoder_update_mst_stream_allocation_table(
-+ link_encoder,
-+ &table,
-+ false);
-+
-+ dc_helpers_dp_mst_poll_for_allocation_change_trigger(
-+ stream->ctx,
-+ &stream->sink->public);
-+
-+ dc_helpers_dp_mst_send_payload_allocation(
-+ stream->ctx,
-+ &stream->sink->public,
-+ true);
-+
-+ avg_time_slots_per_mtp = dal_fixed31_32_from_fraction(
-+ table.stream_allocations[0].pbn,
-+ table.stream_allocations[0].pbn_per_slot);
-+
-+ dce110_link_encoder_set_mst_bandwidth(
-+ link_encoder,
-+ stream_encoder->id,
-+ avg_time_slots_per_mtp);
-+
-+ return DC_OK;
-+
-+}
-+
-+static enum dc_status deallocate_mst_payload(struct core_stream *stream)
-+{
-+ struct link_encoder *link_encoder = stream->sink->link->link_enc;
-+ struct stream_encoder *stream_encoder = stream->stream_enc;
-+ struct dp_mst_stream_allocation_table table;
-+ struct fixed31_32 avg_time_slots_per_mtp = dal_fixed31_32_from_int(0);
-+
-+ /* TODO: remove hardcode */
-+ table.stream_count = 1;
-+ table.stream_allocations[0].slot_count = 0;
-+
-+ dce110_link_encoder_set_mst_bandwidth(
-+ link_encoder,
-+ stream_encoder->id,
-+ avg_time_slots_per_mtp);
-+
-+ dc_helpers_dp_mst_write_payload_allocation_table(
-+ stream->ctx,
-+ &stream->sink->public,
-+ &table.stream_allocations[0],
-+ false);
-+
-+ dce110_link_encoder_update_mst_stream_allocation_table(
-+ link_encoder,
-+ &table,
-+ false);
-+
-+ dc_helpers_dp_mst_poll_for_allocation_change_trigger(
-+ stream->ctx,
-+ &stream->sink->public);
-+
-+ dc_helpers_dp_mst_send_payload_allocation(
-+ stream->ctx,
-+ &stream->sink->public,
-+ false);
-+
-+
-+ return DC_OK;
-+
-+}
-+
-+static enum dc_status apply_single_controller_ctx_to_hw(uint8_t controller_idx,
-+ struct validate_context *context,
-+ const struct dc *dc)
-+{
-+ struct core_stream *stream =
-+ context->res_ctx.controller_ctx[controller_idx].stream;
-+
-+ struct output_pixel_processor *opp =
-+ context->res_ctx.pool.opps[controller_idx];
-+ bool timing_changed = context->res_ctx.controller_ctx[controller_idx]
-+ .flags.timing_changed;
-+ enum color_space color_space;
-+
-+ if (timing_changed) {
-+
-+ disable_stream(stream);
-+ core_link_disable(stream);
-+
-+ /*TODO: AUTO check if timing changed*/
-+ if (false == dal_clock_source_program_pix_clk(
-+ stream->clock_source,
-+ &stream->pix_clk_params,
-+ &stream->pll_settings)) {
-+ BREAK_TO_DEBUGGER();
-+ return DC_ERROR_UNEXPECTED;
-+ }
-+
-+
-+ if (false == dce110_timing_generator_program_timing_generator(
-+ stream->tg,
-+ &stream->public.timing)) {
-+ BREAK_TO_DEBUGGER();
-+ return DC_ERROR_UNEXPECTED;
-+ }
-+ }
-+
-+ /*TODO: mst support - use total stream count*/
-+ dce110_allocate_dmif_buffer(stream->mi,
-+ &stream->public.timing,
-+ context->target_count);
-+
-+ if (timing_changed) {
-+ if (false == dce110_timing_generator_enable_crtc(
-+ stream->tg)) {
-+ BREAK_TO_DEBUGGER();
-+ return DC_ERROR_UNEXPECTED;
-+ }
-+ }
-+
-+ if (DC_OK != bios_parser_crtc_source_select(stream)) {
-+ BREAK_TO_DEBUGGER();
-+ return DC_ERROR_UNEXPECTED;
-+ }
-+
-+ dce110_opp_set_dyn_expansion(
-+ opp,
-+ COLOR_SPACE_YCBCR601,
-+ stream->public.timing.display_color_depth,
-+ stream->sink->public.sink_signal);
-+
-+ program_fmt(
-+ opp,
-+ &stream->fmt_bit_depth,
-+ &stream->clamping);
-+
-+ dce110_link_encoder_setup(
-+ stream->sink->link->link_enc,
-+ stream->signal);
-+ if (ENCODER_RESULT_OK != dce110_stream_encoder_setup(
-+ stream->stream_enc,
-+ &stream->public.timing,
-+ stream->signal,
-+ stream->audio != NULL)) {
-+ BREAK_TO_DEBUGGER();
-+ return DC_ERROR_UNEXPECTED;
-+ }
-+
-+ if (stream->audio != NULL) {
-+ if (AUDIO_RESULT_OK != dal_audio_setup(
-+ stream->audio,
-+ &stream->audio_output,
-+ &stream->public.audio_info)) {
-+ BREAK_TO_DEBUGGER();
-+ return DC_ERROR_UNEXPECTED;
-+ }
-+ }
-+
-+ /* Setup audio rate clock source */
-+ if (stream->audio != NULL)
-+ dal_audio_setup_audio_wall_dto(
-+ stream->audio,
-+ stream->signal,
-+ &stream->audio_output.crtc_info,
-+ &stream->audio_output.pll_info);
-+
-+ /* program blank color */
-+ color_space = get_output_color_space(
-+ &stream->public.timing);
-+
-+ dce110_timing_generator_program_blank_color(
-+ context->res_ctx.pool.timing_generators[controller_idx],
-+ color_space);
-+
-+ if (timing_changed) {
-+ enable_stream(stream);
-+
-+ if (DC_OK != core_link_enable(stream)) {
-+ BREAK_TO_DEBUGGER();
-+ return DC_ERROR_UNEXPECTED;
-+ }
-+ if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
-+ allocate_mst_payload(stream);
-+
-+ }
-+
-+ unblank_stream(stream, &stream->sink->link->cur_link_settings);
-+
-+ return DC_OK;
-+}
-+
-+
-+/******************************************************************************/
-+
-+static void power_down_encoders(struct validate_context *context)
-+{
-+ int i;
-+ struct core_target *target;
-+ struct core_stream *stream;
-+
-+ for (i = 0; i < context->target_count; i++) {
-+ target = context->targets[i];
-+ stream = target->streams[0];
-+ core_link_disable(stream);
-+ }
-+}
-+
-+static void power_down_controllers(struct validate_context *context)
-+{
-+ int i;
-+ struct core_target *target;
-+ struct core_stream *stream;
-+
-+ for (i = 0; i < context->target_count; i++) {
-+ target = context->targets[i];
-+ stream = target->streams[0];
-+
-+ dce110_timing_generator_disable_crtc(stream->tg);
-+ }
-+}
-+
-+static void power_down_clock_sources(struct validate_context *context)
-+{
-+ int i;
-+ struct core_target *target;
-+ struct core_stream *stream;
-+
-+ for (i = 0; i < context->target_count; i++) {
-+ target = context->targets[i];
-+ stream = target->streams[0];
-+
-+ if (false == dal_clock_source_power_down_pll(
-+ stream->clock_source,
-+ stream->controller_idx + 1)) {
-+ dal_error(
-+ "Failed to power down pll! (clk src index=%d)\n",
-+ i);
-+ }
-+ }
-+}
-+
-+static void power_down_all_hw_blocks(struct validate_context *context)
-+{
-+ power_down_encoders(context);
-+
-+ power_down_controllers(context);
-+
-+ power_down_clock_sources(context);
-+}
-+
-+static void disable_vga_and_power_gate_all_controllers(
-+ struct validate_context *context)
-+{
-+ int i;
-+ struct core_target *target;
-+ struct core_stream *stream;
-+ struct timing_generator *tg;
-+ struct bios_parser *bp;
-+ struct dc_context *ctx;
-+ uint8_t controller_id;
-+
-+ bp = dal_adapter_service_get_bios_parser(
-+ context->res_ctx.pool.adapter_srv);
-+
-+ for (i = 0; i < context->target_count; i++) {
-+ target = context->targets[i];
-+ stream = target->streams[0];
-+ tg = stream->tg;
-+ ctx = stream->ctx;
-+ controller_id = stream->controller_idx;
-+
-+ dce110_timing_generator_disable_vga(tg);
-+
-+ /* Enable CLOCK gating for each pipe BEFORE controller
-+ * powergating. */
-+ dce110_enable_display_pipe_clock_gating(ctx,
-+ true);
-+ dce110_enable_display_power_gating(ctx, controller_id, bp,
-+ PIPE_GATING_CONTROL_ENABLE);
-+ }
-+}
-+
-+/**
-+ * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need:
-+ * 1. Power down all DC HW blocks
-+ * 2. Disable VGA engine on all controllers
-+ * 3. Enable power gating for controller
-+ * 4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS)
-+ */
-+static void enable_accelerated_mode(struct validate_context *context)
-+{
-+ struct bios_parser *bp;
-+
-+ bp = dal_adapter_service_get_bios_parser(
-+ context->res_ctx.pool.adapter_srv);
-+
-+ power_down_all_hw_blocks(context);
-+
-+ disable_vga_and_power_gate_all_controllers(context);
-+
-+ dal_bios_parser_set_scratch_acc_mode_change(bp);
-+}
-+
-+#if 0
-+static enum clocks_state get_required_clocks_state(
-+ struct display_clock *display_clock,
-+ struct state_dependent_clocks *req_state_dep_clks)
-+{
-+ enum clocks_state clocks_required_state;
-+ enum clocks_state dp_link_required_state;
-+ enum clocks_state overall_required_state;
-+
-+ clocks_required_state = dal_display_clock_get_required_clocks_state(
-+ display_clock, req_state_dep_clks);
-+
-+ dp_link_required_state = CLOCKS_STATE_ULTRA_LOW;
-+
-+ /* overall required state is the max of required state for clocks
-+ * (pixel, display clock) and the required state for DP link. */
-+ overall_required_state =
-+ clocks_required_state > dp_link_required_state ?
-+ clocks_required_state : dp_link_required_state;
-+
-+ /* return the min required state */
-+ return overall_required_state;
-+}
-+
-+static bool dc_pre_clock_change(
-+ struct dc_context *ctx,
-+ struct minimum_clocks_calculation_result *min_clk_in,
-+ enum clocks_state required_clocks_state,
-+ struct power_to_dal_info *output)
-+{
-+ struct dal_to_power_info input = {0};
-+
-+ input.min_deep_sleep_sclk = min_clk_in->min_deep_sleep_sclk;
-+ input.min_mclk = min_clk_in->min_mclk_khz;
-+ input.min_sclk = min_clk_in->min_sclk_khz;
-+
-+ switch (required_clocks_state) {
-+ case CLOCKS_STATE_ULTRA_LOW:
-+ input.required_clock = PP_CLOCKS_STATE_ULTRA_LOW;
-+ break;
-+ case CLOCKS_STATE_LOW:
-+ input.required_clock = PP_CLOCKS_STATE_LOW;
-+ break;
-+ case CLOCKS_STATE_NOMINAL:
-+ input.required_clock = PP_CLOCKS_STATE_NOMINAL;
-+ break;
-+ case CLOCKS_STATE_PERFORMANCE:
-+ input.required_clock = PP_CLOCKS_STATE_PERFORMANCE;
-+ break;
-+ default:
-+ input.required_clock = PP_CLOCKS_STATE_NOMINAL;
-+ break;
-+ }
-+
-+ if (!dc_service_pp_pre_dce_clock_change(ctx, &input, output)) {
-+ dal_error("DC: dc_service_pp_pre_dce_clock_change failed!\n");
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+static bool dc_set_clocks_and_clock_state (
-+ struct validate_context *context)
-+{
-+ struct power_to_dal_info output = {0};
-+
-+ struct display_clock *disp_clk = context->res_ctx.pool.display_clock;
-+ struct dc_context *ctx = context->targets[0]->ctx;
-+
-+
-+ if (!dc_pre_clock_change(
-+ ctx,
-+ &context->res_ctx.min_clocks,
-+ get_required_clocks_state(
-+ context->res_ctx.pool.display_clock,
-+ &context->res_ctx.state_clocks),
-+ &output)) {
-+ /* "output" was not updated by PPLib.
-+ * DAL will use default values for set mode.
-+ *
-+ * Do NOT fail this call. */
-+ return true;
-+ }
-+
-+ /* PPLib accepted the "clock state" that we need, that means we
-+ * can store it as minimum state because PPLib guarantees not go below
-+ * that state.
-+ *
-+ * Update the clock state here (prior to setting Pixel clock,
-+ * DVO clock, or Display clock) */
-+ if (!dal_display_clock_set_min_clocks_state(
-+ disp_clk, context->res_ctx.required_clocks_state)) {
-+ BREAK_TO_DEBUGGER();
-+ dal_error("DC: failed to set minimum clock state!\n");
-+ }
-+
-+
-+ /*bm_clk_info.max_mclk_khz = output.max_mclk;
-+ bm_clk_info.min_mclk_khz = output.min_mclk;
-+ bm_clk_info.max_sclk_khz = output.max_sclk;
-+ bm_clk_info.min_sclk_khz = output.min_sclk;*/
-+
-+ /* Now let Bandwidth Manager know about values we got from PPLib. */
-+ /*dal_bandwidth_manager_set_dynamic_clock_info(bw_mgr, &bm_clk_info);*/
-+
-+ return true;
-+}
-+#endif
-+
-+/**
-+ * Call display_engine_clock_dce80 to perform the Dclk programming.
-+ */
-+static void set_display_clock(struct validate_context *context)
-+{
-+ /* Program the display engine clock.
-+ * Check DFS bypass mode support or not. DFSbypass feature is only when
-+ * BIOS GPU info table reports support. */
-+
-+ if (/*dal_adapter_service_is_dfs_bypass_enabled()*/ false) {
-+ /*TODO: set_display_clock_dfs_bypass(
-+ hws,
-+ path_set,
-+ context->res_ctx.pool.display_clock,
-+ context->res_ctx.min_clocks.min_dclk_khz);*/
-+ } else
-+ dal_display_clock_set_clock(context->res_ctx.pool.display_clock,
-+ context->bw_results.dispclk);
-+
-+ /* TODO: When changing display engine clock, DMCU WaitLoop must be
-+ * reconfigured in order to maintain the same delays within DMCU
-+ * programming sequences. */
-+
-+ /* TODO: Start GTC counter */
-+}
-+
-+static void set_displaymarks(
-+ const struct dc *dc, struct validate_context *context)
-+{
-+ uint8_t i, j;
-+ uint8_t total_streams = 0;
-+ uint8_t target_count = context->target_count;
-+
-+ for (i = 0; i < target_count; i++) {
-+ struct core_target *target = context->targets[i];
-+
-+ for (j = 0; j < target->stream_count; j++) {
-+ struct core_stream *stream = target->streams[j];
-+
-+ dce110_program_nbp_watermark(
-+ stream->mi,
-+ context->bw_results
-+ .nbp_state_change_watermark[total_streams]);
-+
-+ dce110_program_stutter_watermark(
-+ stream->mi,
-+ context->bw_results
-+ .stutter_exit_watermark[total_streams]);
-+
-+ dce110_program_urgency_watermark(
-+ stream->mi,
-+ context->bw_results
-+ .urgent_watermark[total_streams],
-+ stream->public.timing.h_total,
-+ stream->public.timing.pix_clk_khz,
-+ 1000 * dc->bw_vbios.blackout_duration
-+ .value >> 24);
-+ total_streams++;
-+ }
-+ }
-+}
-+
-+static void set_safe_displaymarks(struct validate_context *context)
-+{
-+ uint8_t i, j;
-+ uint8_t target_count = context->target_count;
-+
-+ for (i = 0; i < target_count; i++) {
-+ struct core_target *target = context->targets[i];
-+
-+ for (j = 0; j < target->stream_count; j++) {
-+ struct core_stream *stream = target->streams[j];
-+
-+ dce110_program_safe_display_marks(stream->mi);
-+ }
-+ }
-+}
-+
-+static void dce110_program_bw(struct dc *dc, struct validate_context *context)
-+{
-+ set_safe_displaymarks(&dc->current_context);
-+ /*TODO: when pplib works*/
-+ /*dc_set_clocks_and_clock_state(context);*/
-+
-+ set_display_clock(&dc->current_context);
-+ set_displaymarks(dc, &dc->current_context);
-+}
-+
-+/*TODO: break out clock sources like timing gen/ encoder*/
-+static void dce110_switch_dp_clk_src(
-+ const struct dc_context *ctx,
-+ const struct core_stream *stream)
-+{
-+ uint32_t pixel_rate_cntl_value;
-+ uint32_t addr;
-+ enum clock_source_id id = dal_clock_source_get_id(stream->clock_source);
-+
-+ /*TODO: proper offset*/
-+ addr = mmCRTC0_PIXEL_RATE_CNTL + stream->controller_idx *
-+ (mmCRTC1_PIXEL_RATE_CNTL - mmCRTC0_PIXEL_RATE_CNTL);
-+
-+ pixel_rate_cntl_value = dal_read_reg(ctx, addr);
-+
-+ if (id == CLOCK_SOURCE_ID_EXTERNAL) {
-+
-+ if (!get_reg_field_value(pixel_rate_cntl_value,
-+ CRTC0_PIXEL_RATE_CNTL, DP_DTO0_ENABLE)) {
-+
-+ set_reg_field_value(pixel_rate_cntl_value, 1,
-+ CRTC0_PIXEL_RATE_CNTL, DP_DTO0_ENABLE);
-+ }
-+
-+ } else {
-+ set_reg_field_value(pixel_rate_cntl_value,
-+ 0,
-+ CRTC0_PIXEL_RATE_CNTL,
-+ DP_DTO0_ENABLE);
-+
-+ set_reg_field_value(pixel_rate_cntl_value,
-+ id - 1,
-+ CRTC0_PIXEL_RATE_CNTL,
-+ CRTC0_PIXEL_RATE_SOURCE);
-+ }
-+ dal_write_reg(ctx, addr, pixel_rate_cntl_value);
-+}
-+
-+static void switch_dp_clock_sources(
-+ const struct dc_context *ctx,
-+ struct validate_context *val_context)
-+{
-+ uint8_t i, j;
-+ for (i = 0; i < val_context->target_count; i++) {
-+ struct core_target *target = val_context->targets[i];
-+ for (j = 0; j < target->stream_count; j++) {
-+ struct core_stream *stream = target->streams[j];
-+
-+ if (dc_is_dp_signal(stream->signal)) {
-+ struct clock_source *clk_src =
-+ find_used_clk_src_for_sharing(
-+ val_context, stream);
-+
-+ if (clk_src != stream->clock_source) {
-+ unreference_clock_source(
-+ &val_context->res_ctx,
-+ stream->clock_source);
-+ stream->clock_source = clk_src;
-+ reference_clock_source(
-+ &val_context->res_ctx, clk_src);
-+ dce110_switch_dp_clk_src(ctx, stream);
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+/*******************************************************************************
-+ * Public functions
-+ ******************************************************************************/
-+
-+/*TODO: const validate_context*/
-+static enum dc_status apply_ctx_to_hw(
-+ const struct dc *dc,
-+ struct validate_context *context)
-+{
-+ enum dc_status status;
-+ uint8_t i;
-+ struct resource_pool *pool = &context->res_ctx.pool;
-+
-+ update_bios_scratch_critical_state(context->res_ctx.pool.adapter_srv,
-+ true);
-+ set_safe_displaymarks(context);
-+ /*TODO: when pplib works*/
-+ /*dc_set_clocks_and_clock_state(context);*/
-+
-+ set_display_clock(context);
-+
-+ for (i = 0; i < pool->controller_count; i++) {
-+ struct controller_ctx *ctlr_ctx
-+ = &context->res_ctx.controller_ctx[i];
-+ if (ctlr_ctx->flags.unchanged || !ctlr_ctx->stream)
-+ continue;
-+
-+ status = apply_single_controller_ctx_to_hw(
-+ i,
-+ context,
-+ dc);
-+
-+ if (DC_OK != status)
-+ return status;
-+ }
-+ set_displaymarks(dc, context);
-+
-+ update_bios_scratch_critical_state(context->res_ctx.pool.adapter_srv,
-+ false);
-+
-+ switch_dp_clock_sources(dc->ctx, context);
-+
-+ return DC_OK;
-+}
-+
-+
-+/*******************************************************************************
-+ * Front End programming
-+ ******************************************************************************/
-+
-+static bool setup_line_buffer_pixel_depth(
-+ const struct core_stream *stream,
-+ enum lb_pixel_depth depth,
-+ bool blank)
-+{
-+ enum lb_pixel_depth current_depth;
-+
-+ struct timing_generator *tg = stream->tg;
-+ struct transform *xfm = stream->xfm;
-+
-+ if (!dce110_transform_get_current_pixel_storage_depth(
-+ xfm,
-+ &current_depth))
-+ return false;
-+
-+ if (current_depth != depth) {
-+ if (blank)
-+ dce110_timing_generator_wait_for_vblank(tg);
-+
-+ return dce110_transform_set_pixel_storage_depth(xfm, depth);
-+ }
-+
-+ return false;
-+}
-+
-+static void hw_sequencer_build_scaler_parameter_plane(
-+ const struct core_stream *stream,
-+ struct scaler_data *scaler_data)
-+{
-+ /*TODO: per pipe not per stream*/
-+ /*TODO: get from feature from adapterservice*/
-+ scaler_data->flags.bits.SHOW_COLOURED_BORDER = false;
-+
-+ scaler_data->flags.bits.SHOULD_PROGRAM_ALPHA = 1;
-+
-+ scaler_data->flags.bits.SHOULD_PROGRAM_VIEWPORT = 0;
-+
-+ scaler_data->flags.bits.SHOULD_UNLOCK = 0;
-+
-+ scaler_data->flags.bits.INTERLACED = 0;
-+
-+ scaler_data->dal_pixel_format = stream->format;
-+
-+ scaler_data->taps = stream->taps;
-+
-+ scaler_data->viewport = stream->viewport;
-+
-+ scaler_data->overscan = stream->overscan;
-+
-+ scaler_data->ratios = &stream->ratios;
-+
-+ /*TODO rotation and adjustment */
-+ scaler_data->h_sharpness = 0;
-+ scaler_data->v_sharpness = 0;
-+
-+}
-+
-+static void set_default_colors(
-+ struct input_pixel_processor *ipp,
-+ struct output_pixel_processor *opp,
-+ enum pixel_format format,
-+ enum color_space input_color_space,
-+ enum color_space output_color_space,
-+ enum dc_color_depth color_depth)
-+{
-+ struct default_adjustment default_adjust = { 0 };
-+
-+ default_adjust.force_hw_default = false;
-+ default_adjust.color_space = output_color_space;
-+ default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW;
-+ default_adjust.surface_pixel_format = format;
-+
-+ /* display color depth */
-+ default_adjust.color_depth = color_depth;
-+
-+ /* Lb color depth */
-+ default_adjust.lb_color_depth = LB_PIXEL_DEPTH_24BPP;
-+ /*dal_hw_sequencer_translate_to_lb_color_depth(
-+ build_params->
-+ line_buffer_params[path_id][plane_id].depth);*/
-+
-+ dce110_opp_set_csc_default(opp, &default_adjust);
-+}
-+
-+static void program_scaler(
-+ uint8_t controller_idx,
-+ struct timing_generator *tg,
-+ struct transform *xfm,
-+ const struct core_surface *surface,
-+ const struct core_stream *stream)
-+{
-+ struct scaler_data scaler_data = { { 0 } };
-+
-+ hw_sequencer_build_scaler_parameter_plane(
-+ stream,
-+ &scaler_data);
-+
-+ setup_line_buffer_pixel_depth(
-+ stream,
-+ LB_PIXEL_DEPTH_24BPP,
-+ false);
-+
-+ dce110_timing_generator_set_overscan_color_black(
-+ tg,
-+ surface->public.colorimetry.color_space);
-+
-+ dce110_transform_set_scaler(xfm, &scaler_data);
-+
-+ dce110_transform_update_viewport(
-+ xfm,
-+ &scaler_data.viewport,
-+ false);
-+}
-+
-+
-+
-+static void configure_locking(struct dc_context *ctx, uint8_t controller_id)
-+{
-+ /* main controller should be in mode 0 (master pipe) */
-+ pipe_control_lock(
-+ ctx,
-+ controller_id,
-+ PIPE_LOCK_CONTROL_MODE,
-+ false);
-+
-+ /* TODO: for MPO finish the non-root controllers */
-+}
-+
-+/**
-+ * Program the Front End of the Pipe.
-+ * The Back End was already programmed by Set Mode.
-+ */
-+static bool set_plane_config(
-+ struct core_surface *surface,
-+ struct core_target *target)
-+{
-+ const struct dc_crtc_timing *dc_crtc_timing =
-+ &target->streams[0]->public.timing;
-+ struct mem_input *mi = target->streams[0]->mi;
-+ struct input_pixel_processor *ipp = target->streams[0]->ipp;
-+ struct timing_generator *tg = target->streams[0]->tg;
-+ struct transform *xfm = target->streams[0]->xfm;
-+ struct output_pixel_processor *opp = target->streams[0]->opp;
-+ struct dc_context *ctx = target->streams[0]->ctx;
-+ uint8_t controller_idx = target->streams[0]->controller_idx;
-+
-+ /* TODO: Clean up change, possibly change to use same type */
-+ enum color_space input_color_space =
-+ surface_color_to_color_space(&(surface->public.colorimetry));
-+
-+ configure_locking(ctx, controller_idx);
-+
-+ /* While a non-root controller is programmed we
-+ * have to lock the root controller. */
-+ pipe_control_lock(
-+ ctx,
-+ controller_idx,
-+ PIPE_LOCK_CONTROL_GRAPHICS |
-+ PIPE_LOCK_CONTROL_SCL |
-+ PIPE_LOCK_CONTROL_BLENDER |
-+ PIPE_LOCK_CONTROL_SURFACE,
-+ true);
-+
-+ dce110_program_pix_dur(mi, dc_crtc_timing->pix_clk_khz);
-+
-+ dce110_timing_generator_program_blanking(tg, dc_crtc_timing);
-+
-+ enable_fe_clock(ctx, controller_idx, true);
-+
-+ set_default_colors(
-+ ipp,
-+ opp,
-+ target->streams[0]->format,
-+ input_color_space,
-+ get_output_color_space(dc_crtc_timing),
-+ dc_crtc_timing->display_color_depth);
-+
-+ /* program Scaler */
-+ program_scaler(
-+ controller_idx, tg, xfm, surface, target->streams[0]);
-+
-+ set_blender_mode(
-+ ctx,
-+ controller_idx,
-+ BLENDER_MODE_CURRENT_PIPE);
-+
-+#if 0
-+ program_alpha_mode(
-+ crtc,
-+ &pl_cfg->attributes.blend_flags,
-+ path_mode->mode.timing.pixel_encoding);
-+#endif
-+
-+ dce110_mem_input_program_surface_config(
-+ mi,
-+ &surface->public);
-+
-+ pipe_control_lock(
-+ ctx,
-+ controller_idx,
-+ PIPE_LOCK_CONTROL_GRAPHICS |
-+ PIPE_LOCK_CONTROL_SCL |
-+ PIPE_LOCK_CONTROL_BLENDER |
-+ PIPE_LOCK_CONTROL_SURFACE,
-+ false);
-+
-+ return true;
-+}
-+
-+static bool update_plane_address(
-+ const struct core_surface *surface,
-+ struct core_target *target)
-+{
-+ struct dc_context *ctx = target->streams[0]->ctx;
-+ struct mem_input *mi = target->streams[0]->mi;
-+ uint8_t controller_id = target->streams[0]->controller_idx;
-+
-+ /* TODO: crtc should be per surface, NOT per-target */
-+ pipe_control_lock(
-+ ctx,
-+ controller_id,
-+ PIPE_LOCK_CONTROL_SURFACE,
-+ true);
-+
-+ if (false == dce110_mem_input_program_surface_flip_and_addr(
-+ mi, &surface->public.address, surface->public.flip_immediate))
-+ return false;
-+
-+ pipe_control_lock(
-+ ctx,
-+ controller_id,
-+ PIPE_LOCK_CONTROL_SURFACE,
-+ false);
-+
-+ return true;
-+}
-+
-+static void reset_single_stream_hw_ctx(struct core_stream *stream,
-+ struct validate_context *context)
-+{
-+ if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
-+ deallocate_mst_payload(stream);
-+
-+ disable_stream(stream);
-+ if (stream->audio) {
-+ dal_audio_disable_output(stream->audio,
-+ stream->stream_enc->id,
-+ stream->signal);
-+ stream->audio = NULL;
-+ }
-+
-+ core_link_disable(stream);
-+ dce110_timing_generator_blank_crtc(stream->tg);
-+ dce110_timing_generator_disable_crtc(stream->tg);
-+ dce110_deallocate_dmif_buffer(stream->mi, context->target_count);
-+ dce110_transform_set_scaler_bypass(stream->xfm);
-+ disable_stereo_mixer(stream->ctx);
-+ unreference_clock_source(&context->res_ctx, stream->clock_source);
-+}
-+
-+static void reset_hw_ctx(struct dc *dc,
-+ struct validate_context *context,
-+ uint8_t target_count)
-+{
-+ uint8_t i;
-+ /* look up the targets that have been removed since last commit */
-+ for (i = 0; i < dc->current_context.target_count; i++) {
-+ uint8_t controller_idx = dc->current_context.targets[i]->
-+ streams[0]->controller_idx;
-+
-+ if (context->res_ctx.controller_ctx[controller_idx].stream &&
-+ !context->res_ctx.controller_ctx[controller_idx]
-+ .flags.timing_changed)
-+ continue;
-+
-+ reset_single_stream_hw_ctx(
-+ dc->current_context.targets[i]->streams[0],
-+ &dc->current_context);
-+ }
-+}
-+
-+static void power_down(struct validate_context *context)
-+{
-+ power_down_all_hw_blocks(context);
-+ disable_vga_and_power_gate_all_controllers(context);
-+
-+}
-+
-+static bool wait_for_reset_trigger_to_occur(
-+ struct dc_context *dc_ctx,
-+ struct timing_generator *tg)
-+{
-+ bool rc = false;
-+
-+ /* To avoid endless loop we wait at most
-+ * frames_to_wait_on_triggered_reset frames for the reset to occur. */
-+ const uint32_t frames_to_wait_on_triggered_reset = 10;
-+ uint32_t i;
-+
-+ for (i = 0; i < frames_to_wait_on_triggered_reset; i++) {
-+
-+ if (!dce110_timing_generator_is_counter_moving(tg)) {
-+ DC_ERROR("TG counter is not moving!\n");
-+ break;
-+ }
-+
-+ if (dce110_timing_generator_did_triggered_reset_occur(tg)) {
-+ rc = true;
-+ /* usually occurs at i=1 */
-+ DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n",
-+ i);
-+ break;
-+ }
-+
-+ /* Wait for one frame. */
-+ dce110_timing_generator_wait_for_vactive(tg);
-+ dce110_timing_generator_wait_for_vblank(tg);
-+ }
-+
-+ if (false == rc)
-+ DC_ERROR("GSL: Timeout on reset trigger!\n");
-+
-+ return rc;
-+}
-+
-+/* Enable timing synchronization for a group of Timing Generators. */
-+static void enable_timing_synchronization(
-+ struct dc_context *dc_ctx,
-+ uint32_t timing_generator_num,
-+ struct timing_generator *tgs[])
-+{
-+ struct dcp_gsl_params gsl_params = { 0 };
-+ struct trigger_params trigger_params;
-+ uint32_t i;
-+
-+ DC_SYNC_INFO("GSL: Setting-up...\n");
-+
-+ gsl_params.gsl_group = SYNC_SOURCE_GSL_GROUP0;
-+ gsl_params.gsl_purpose = DCP_GSL_PURPOSE_SURFACE_FLIP;
-+
-+ for (i = 0; i < timing_generator_num; i++) {
-+ /* Designate a single TG in the group as a master.
-+ * Since HW doesn't care which one, we always assign
-+ * the 1st one in the group. */
-+ gsl_params.timing_server = (0 == i ? true : false);
-+
-+ dce110_timing_generator_setup_global_swap_lock(tgs[i],
-+ &gsl_params);
-+ }
-+
-+ /* Reset slave controllers on master VSync */
-+ DC_SYNC_INFO("GSL: enabling trigger-reset\n");
-+ dc_service_memset(&trigger_params, 0, sizeof(trigger_params));
-+
-+ trigger_params.edge = TRIGGER_EDGE_DEFAULT;
-+ trigger_params.source = SYNC_SOURCE_GSL_GROUP0;
-+
-+ for (i = 1 /* skip the master */; i < timing_generator_num; i++) {
-+ dce110_timing_generator_enable_reset_trigger(tgs[i],
-+ &trigger_params);
-+
-+ DC_SYNC_INFO("GSL: waiting for reset to occur.\n");
-+ wait_for_reset_trigger_to_occur(dc_ctx, tgs[i]);
-+
-+ /* Regardless of success of the wait above, remove the reset or
-+ * the driver will start timing out on Display requests. */
-+ DC_SYNC_INFO("GSL: disabling trigger-reset.\n");
-+ dce110_timing_generator_disable_reset_trigger(tgs[i]);
-+ }
-+
-+ /* GSL Vblank synchronization is a one time sync mechanism, assumption
-+ * is that the sync'ed displays will not drift out of sync over time*/
-+ DC_SYNC_INFO("GSL: Restoring register states.\n");
-+ for (i = 0; i < timing_generator_num; i++)
-+ dce110_timing_generator_tear_down_global_swap_lock(tgs[i]);
-+
-+ DC_SYNC_INFO("GSL: Set-up complete.\n");
-+}
-+
-+
-+static const struct hw_sequencer_funcs dce110_funcs = {
-+ .apply_ctx_to_hw = apply_ctx_to_hw,
-+ .reset_hw_ctx = reset_hw_ctx,
-+ .set_plane_config = set_plane_config,
-+ .update_plane_address = update_plane_address,
-+ .enable_memory_requests = dce110_timing_generator_unblank_crtc,
-+ .disable_memory_requests = dce110_timing_generator_blank_crtc,
-+ .cursor_set_attributes = dce110_ipp_cursor_set_attributes,
-+ .cursor_set_position = dce110_ipp_cursor_set_position,
-+ .set_gamma_ramp = set_gamma_ramp,
-+ .power_down = power_down,
-+ .enable_accelerated_mode = enable_accelerated_mode,
-+ .get_crtc_positions = dce110_timing_generator_get_crtc_positions,
-+ .get_vblank_counter = dce110_timing_generator_get_vblank_counter,
-+ .enable_timing_synchronization = enable_timing_synchronization,
-+ .disable_vga = dce110_timing_generator_disable_vga,
-+ .encoder_create = dce110_link_encoder_create,
-+ .encoder_destroy = dce110_link_encoder_destroy,
-+ .encoder_power_up = dce110_link_encoder_power_up,
-+ .encoder_enable_output = dce110_link_encoder_enable_output,
-+ .encoder_disable_output = dce110_link_encoder_disable_output,
-+ .encoder_set_dp_phy_pattern = dce110_link_encoder_set_dp_phy_pattern,
-+ .encoder_dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings,
-+ .encoder_set_lcd_backlight_level = dce110_link_encoder_set_lcd_backlight_level,
-+ .clock_gating_power_up = dal_dc_clock_gating_dce110_power_up,
-+ .transform_power_up = dce110_transform_power_up,
-+ .construct_resource_pool = dce110_construct_resource_pool,
-+ .destruct_resource_pool = dce110_destruct_resource_pool,
-+ .validate_with_context = dce110_validate_with_context,
-+ .validate_bandwidth = dce110_validate_bandwidth,
-+ .set_afmt_memory_power_state = dce110_set_afmt_memory_power_state,
-+ .enable_display_pipe_clock_gating = dce110_enable_display_pipe_clock_gating,
-+ .enable_display_power_gating = dce110_enable_display_power_gating,
-+ .program_bw = dce110_program_bw
-+};
-+
-+bool dce110_hw_sequencer_construct(struct dc *dc)
-+{
-+ dc->hwss = dce110_funcs;
-+
-+ return true;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.h
-new file mode 100644
-index 0000000..def54df
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.h
-@@ -0,0 +1,36 @@
-+/*
-+* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_HWSS_DCE110_H__
-+#define __DC_HWSS_DCE110_H__
-+
-+#include "core_types.h"
-+
-+struct dc;
-+
-+bool dce110_hw_sequencer_construct(struct dc *dc);
-+
-+#endif /* __DC_HWSS_DCE110_H__ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp.c
-new file mode 100644
-index 0000000..04105ed
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp.c
-@@ -0,0 +1,85 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/logger_interface.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "dce110_ipp.h"
-+
-+static const struct dce110_ipp_reg_offsets reg_offsets[] = {
-+{
-+ .dcp_offset = (mmDCP0_CUR_CONTROL - mmDCP0_CUR_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP1_CUR_CONTROL - mmDCP0_CUR_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP2_CUR_CONTROL - mmDCP0_CUR_CONTROL),
-+}
-+};
-+
-+bool dce110_ipp_construct(
-+ struct dce110_ipp* ipp,
-+ struct dc_context *ctx,
-+ uint32_t inst)
-+{
-+ if ((inst < 1) || (inst > ARRAY_SIZE(reg_offsets)))
-+ return false;
-+
-+ ipp->base.ctx = ctx;
-+
-+ ipp->base.inst = inst;
-+
-+ ipp->offsets = reg_offsets[inst-1];
-+
-+ return true;
-+}
-+
-+void dce110_ipp_destroy(struct input_pixel_processor **ipp)
-+{
-+ dc_service_free((*ipp)->ctx, TO_DCE110_IPP(*ipp));
-+ *ipp = NULL;
-+}
-+
-+struct input_pixel_processor *dce110_ipp_create(
-+ struct dc_context *ctx,
-+ uint32_t inst)
-+{
-+ struct dce110_ipp *ipp =
-+ dc_service_alloc(ctx, sizeof(struct dce110_ipp));
-+
-+ if (!ipp)
-+ return NULL;
-+
-+ if (dce110_ipp_construct(ipp, ctx, inst))
-+ return &ipp->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dc_service_free(ctx, ipp);
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp.h
-new file mode 100644
-index 0000000..1da42ff
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp.h
-@@ -0,0 +1,90 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_IPP_DCE110_H__
-+#define __DC_IPP_DCE110_H__
-+
-+#include "inc/ipp.h"
-+
-+#define TO_DCE110_IPP(input_pixel_processor)\
-+ container_of(input_pixel_processor, struct dce110_ipp, base)
-+
-+struct dce110_ipp_reg_offsets {
-+ uint32_t dcp_offset;
-+};
-+
-+struct dce110_ipp {
-+ struct input_pixel_processor base;
-+ struct dce110_ipp_reg_offsets offsets;
-+ struct dev_c_lut saved_palette[RGB_256X3X16];
-+};
-+
-+bool dce110_ipp_construct(
-+ struct dce110_ipp* ipp,
-+ struct dc_context *ctx,
-+ enum controller_id id);
-+
-+void dce110_ipp_destroy(struct input_pixel_processor **ipp);
-+
-+struct input_pixel_processor *dce110_ipp_create(
-+ struct dc_context *ctx,
-+ enum controller_id id);
-+
-+/* CURSOR RELATED */
-+bool dce110_ipp_cursor_set_position(
-+ struct input_pixel_processor *ipp,
-+ const struct dc_cursor_position *position);
-+
-+bool dce110_ipp_cursor_set_attributes(
-+ struct input_pixel_processor *ipp,
-+ const struct dc_cursor_attributes *attributes);
-+
-+/* DEGAMMA RELATED */
-+bool dce110_ipp_set_degamma(
-+ struct input_pixel_processor *ipp,
-+ const struct gamma_parameters *params,
-+ bool force_bypass);
-+
-+void dce110_ipp_program_prescale(
-+ struct input_pixel_processor *ipp,
-+ enum pixel_format pixel_format);
-+
-+void dce110_ipp_set_legacy_input_gamma_mode(
-+ struct input_pixel_processor *ipp,
-+ bool is_legacy);
-+
-+bool dce110_ipp_set_legacy_input_gamma_ramp(
-+ struct input_pixel_processor *ipp,
-+ const struct gamma_ramp *gamma_ramp,
-+ const struct gamma_parameters *params);
-+
-+bool dce110_ipp_set_palette(
-+ struct input_pixel_processor *ipp,
-+ const struct dev_c_lut *palette,
-+ uint32_t start,
-+ uint32_t length,
-+ enum pixel_format surface_pixel_format);
-+
-+#endif /*__DC_IPP_DCE110_H__*/
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp_cursor.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp_cursor.c
-new file mode 100644
-index 0000000..08b7940
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp_cursor.c
-@@ -0,0 +1,256 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/logger_interface.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "dce110_ipp.h"
-+
-+#define CURSOR_COLOR_BLACK 0x00000000
-+#define CURSOR_COLOR_WHITE 0xFFFFFFFF
-+
-+#define DCP_REG(reg)\
-+ (reg + ipp110->offsets.dcp_offset)
-+
-+static void enable(
-+ struct dce110_ipp *ipp110,
-+ bool enable);
-+
-+static void lock(
-+ struct dce110_ipp *ipp110,
-+ bool enable);
-+
-+static void program_position(
-+ struct dce110_ipp *ipp110,
-+ uint32_t x,
-+ uint32_t y);
-+
-+static bool program_control(
-+ struct dce110_ipp *ipp110,
-+ enum dc_cursor_color_format color_format,
-+ bool enable_magnification,
-+ bool inverse_transparent_clamping);
-+
-+static void program_hotspot(
-+ struct dce110_ipp *ipp110,
-+ uint32_t x,
-+ uint32_t y);
-+
-+static void program_size(
-+ struct dce110_ipp *ipp110,
-+ uint32_t width,
-+ uint32_t height);
-+
-+static void program_address(
-+ struct dce110_ipp *ipp110,
-+ PHYSICAL_ADDRESS_LOC address);
-+
-+
-+bool dce110_ipp_cursor_set_position(
-+ struct input_pixel_processor *ipp,
-+ const struct dc_cursor_position *position)
-+{
-+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
-+
-+ /* lock cursor registers */
-+ lock(ipp110, true);
-+
-+ /* Flag passed in structure differentiates cursor enable/disable. */
-+ /* Update if it differs from cached state. */
-+ enable(ipp110, position->enable);
-+
-+ program_position(ipp110, position->x, position->y);
-+
-+ if (position->hot_spot_enable)
-+ program_hotspot(
-+ ipp110,
-+ position->x_origin,
-+ position->y_origin);
-+
-+ /* unlock cursor registers */
-+ lock(ipp110, false);
-+
-+ return true;
-+}
-+
-+bool dce110_ipp_cursor_set_attributes(
-+ struct input_pixel_processor *ipp,
-+ const struct dc_cursor_attributes *attributes)
-+{
-+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
-+ /* Lock cursor registers */
-+ lock(ipp110, true);
-+
-+ /* Program cursor control */
-+ program_control(
-+ ipp110,
-+ attributes->color_format,
-+ attributes->attribute_flags.bits.ENABLE_MAGNIFICATION,
-+ attributes->attribute_flags.bits.INVERSE_TRANSPARENT_CLAMPING);
-+
-+ /* Program hot spot coordinates */
-+ program_hotspot(ipp110, attributes->x_hot, attributes->y_hot);
-+
-+ /*
-+ * Program cursor size -- NOTE: HW spec specifies that HW register
-+ * stores size as (height - 1, width - 1)
-+ */
-+ program_size(ipp110, attributes->width, attributes->height);
-+
-+ /* Program cursor surface address */
-+ program_address(ipp110, attributes->address);
-+
-+ /* Unlock Cursor registers. */
-+ lock(ipp110, false);
-+
-+ return true;
-+}
-+
-+static void enable(
-+ struct dce110_ipp *ipp110, bool enable)
-+{
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmCUR_CONTROL);
-+
-+ value = dal_read_reg(ipp110->base.ctx, addr);
-+ set_reg_field_value(value, enable, CUR_CONTROL, CURSOR_EN);
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+}
-+
-+static void lock(
-+ struct dce110_ipp *ipp110, bool lock)
-+{
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmCUR_UPDATE);
-+
-+ value = dal_read_reg(ipp110->base.ctx, addr);
-+ set_reg_field_value(value, lock, CUR_UPDATE, CURSOR_UPDATE_LOCK);
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+}
-+
-+static void program_position(
-+ struct dce110_ipp *ipp110,
-+ uint32_t x,
-+ uint32_t y)
-+{
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmCUR_POSITION);
-+
-+ value = dal_read_reg(ipp110->base.ctx, addr);
-+ set_reg_field_value(value, x, CUR_POSITION, CURSOR_X_POSITION);
-+ set_reg_field_value(value, y, CUR_POSITION, CURSOR_Y_POSITION);
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+}
-+
-+static bool program_control(
-+ struct dce110_ipp *ipp110,
-+ enum dc_cursor_color_format color_format,
-+ bool enable_magnification,
-+ bool inverse_transparent_clamping)
-+{
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmCUR_CONTROL);
-+ uint32_t mode = 0;
-+
-+ switch (color_format) {
-+ case CURSOR_MODE_MONO:
-+ mode = 0;
-+ break;
-+ case CURSOR_MODE_COLOR_1BIT_AND:
-+ mode = 1;
-+ break;
-+ case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
-+ mode = 2;
-+ break;
-+ case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
-+ mode = 3;
-+ break;
-+ default:
-+ return false;
-+ }
-+
-+ set_reg_field_value(value, mode, CUR_CONTROL, CURSOR_MODE);
-+ set_reg_field_value(value, enable_magnification,
-+ CUR_CONTROL, CURSOR_2X_MAGNIFY);
-+ set_reg_field_value(value, inverse_transparent_clamping,
-+ CUR_CONTROL, CUR_INV_TRANS_CLAMP);
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+
-+ if (color_format == CURSOR_MODE_MONO) {
-+ addr = DCP_REG(mmCUR_COLOR1);
-+ dal_write_reg(ipp110->base.ctx, addr, CURSOR_COLOR_BLACK);
-+ addr = DCP_REG(mmCUR_COLOR2);
-+ dal_write_reg(ipp110->base.ctx, addr, CURSOR_COLOR_WHITE);
-+ }
-+ return true;
-+}
-+
-+static void program_hotspot(
-+ struct dce110_ipp *ipp110,
-+ uint32_t x,
-+ uint32_t y)
-+{
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmCUR_HOT_SPOT);
-+
-+ value = dal_read_reg(ipp110->base.ctx, addr);
-+ set_reg_field_value(value, x, CUR_HOT_SPOT, CURSOR_HOT_SPOT_X);
-+ set_reg_field_value(value, y, CUR_HOT_SPOT, CURSOR_HOT_SPOT_Y);
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+}
-+
-+static void program_size(
-+ struct dce110_ipp *ipp110,
-+ uint32_t width,
-+ uint32_t height)
-+{
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmCUR_SIZE);
-+
-+ value = dal_read_reg(ipp110->base.ctx, addr);
-+ set_reg_field_value(value, width, CUR_SIZE, CURSOR_WIDTH);
-+ set_reg_field_value(value, height, CUR_SIZE, CURSOR_HEIGHT);
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+}
-+
-+static void program_address(
-+ struct dce110_ipp *ipp110,
-+ PHYSICAL_ADDRESS_LOC address)
-+{
-+ uint32_t addr = DCP_REG(mmCUR_SURFACE_ADDRESS_HIGH);
-+ /* SURFACE_ADDRESS_HIGH: Higher order bits (39:32) of hardware cursor
-+ * surface base address in byte. It is 4K byte aligned.
-+ * The correct way to program cursor surface address is to first write
-+ * to CUR_SURFACE_ADDRESS_HIGH, and then write to CUR_SURFACE_ADDRESS */
-+
-+ dal_write_reg(ipp110->base.ctx, addr, address.high_part);
-+
-+ addr = DCP_REG(mmCUR_SURFACE_ADDRESS);
-+ dal_write_reg(ipp110->base.ctx, addr, address.low_part);
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp_gamma.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp_gamma.c
-new file mode 100644
-index 0000000..f2e8ef4
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_ipp_gamma.c
-@@ -0,0 +1,877 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/logger_interface.h"
-+#include "include/fixed31_32.h"
-+#include "basics/conversion.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "dce110_ipp.h"
-+
-+#define DCP_REG(reg)\
-+ (reg + ipp110->offsets.dcp_offset)
-+
-+enum {
-+ MAX_INPUT_LUT_ENTRY = 256
-+};
-+
-+/* CALCULATION OPERATIONS*/
-+static void convert_256_lut_entries_to_gxo_format(
-+ const struct gamma_ramp_rgb256x3x16 *lut,
-+ struct dev_c_lut16 *gamma)
-+{
-+ uint32_t i = 0;
-+
-+ ASSERT(lut);
-+ ASSERT(gamma);
-+
-+ do {
-+ gamma->red = lut->red[i];
-+ gamma->green = lut->green[i];
-+ gamma->blue = lut->blue[i];
-+
-+ ++gamma;
-+ ++i;
-+ } while (i != MAX_INPUT_LUT_ENTRY);
-+}
-+
-+static void convert_udx_gamma_entries_to_gxo_format(
-+ const struct gamma_ramp_dxgi_1 *lut,
-+ struct dev_c_lut16 *gamma)
-+{
-+ /* TODO here we deal with DXGI gamma table,
-+ * originally, values was expressed as 'float',
-+ * now values expressed as 'dal_fixed20_12'. */
-+}
-+
-+/*PROTOTYPE DECLARATIONS*/
-+static void set_lut_inc(
-+ struct dce110_ipp *ipp110,
-+ uint8_t inc,
-+ bool is_float,
-+ bool is_signed);
-+
-+static void select_lut(struct dce110_ipp *ipp110);
-+
-+static void program_black_offsets(
-+ struct dce110_ipp *ipp110,
-+ struct dev_c_lut16 *offset);
-+
-+static void program_white_offsets(
-+ struct dce110_ipp *ipp110,
-+ struct dev_c_lut16 *offset);
-+
-+static void program_black_white_offset(
-+ struct dce110_ipp *ipp110,
-+ enum pixel_format surface_pixel_format);
-+
-+static void program_lut_gamma(
-+ struct dce110_ipp *ipp110,
-+ const struct dev_c_lut16 *gamma,
-+ const struct gamma_parameters *params);
-+
-+static void program_prescale(
-+ struct dce110_ipp *ipp110,
-+ enum pixel_format pixel_format);
-+
-+static void set_legacy_input_gamma_mode(
-+ struct dce110_ipp *ipp110,
-+ bool is_legacy);
-+
-+static bool set_legacy_input_gamma_ramp_rgb256x3x16(
-+ struct dce110_ipp *ipp110,
-+ const struct gamma_ramp *gamma_ramp,
-+ const struct gamma_parameters *params);
-+
-+static bool set_legacy_input_gamma_ramp_dxgi1(
-+ struct dce110_ipp *ipp110,
-+ const struct gamma_ramp *gamma_ramp,
-+ const struct gamma_parameters *params);
-+
-+static bool set_default_gamma(
-+ struct dce110_ipp *ipp110,
-+ enum pixel_format surface_pixel_format);
-+
-+static void set_degamma(
-+ struct dce110_ipp *ipp110,
-+ const struct gamma_parameters *params,
-+ bool force_bypass);
-+
-+bool dce110_ipp_set_legacy_input_gamma_ramp(
-+ struct input_pixel_processor *ipp,
-+ const struct gamma_ramp *gamma_ramp,
-+ const struct gamma_parameters *params)
-+{
-+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
-+
-+ switch (gamma_ramp->type) {
-+ case GAMMA_RAMP_RBG256X3X16:
-+ return set_legacy_input_gamma_ramp_rgb256x3x16(
-+ ipp110, gamma_ramp, params);
-+ case GAMMA_RAMP_DXGI_1:
-+ return set_legacy_input_gamma_ramp_dxgi1(
-+ ipp110, gamma_ramp, params);
-+ default:
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+}
-+
-+bool dce110_ipp_set_palette(
-+ struct input_pixel_processor *ipp,
-+ const struct dev_c_lut *palette,
-+ uint32_t start,
-+ uint32_t length,
-+ enum pixel_format surface_pixel_format)
-+{
-+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
-+ uint32_t i;
-+
-+ if (((start + length) > MAX_INPUT_LUT_ENTRY) || (NULL == palette)) {
-+ BREAK_TO_DEBUGGER();
-+ /* wrong input */
-+ return false;
-+ }
-+
-+ for (i = start; i < start + length; i++) {
-+ ipp110->saved_palette[i] = palette[i];
-+ ipp110->saved_palette[i] = palette[i];
-+ ipp110->saved_palette[i] = palette[i];
-+ }
-+
-+ return set_default_gamma(ipp110, surface_pixel_format);
-+}
-+
-+bool dce110_ipp_set_degamma(
-+ struct input_pixel_processor *ipp,
-+ const struct gamma_parameters *params,
-+ bool force_bypass)
-+{
-+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
-+
-+ set_degamma(ipp110, params, force_bypass);
-+
-+ return true;
-+}
-+
-+void dce110_ipp_program_prescale(
-+ struct input_pixel_processor *ipp,
-+ enum pixel_format pixel_format)
-+{
-+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
-+
-+ program_prescale(ipp110, pixel_format);
-+}
-+
-+void dce110_ipp_set_legacy_input_gamma_mode(
-+ struct input_pixel_processor *ipp,
-+ bool is_legacy)
-+{
-+ struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
-+
-+ set_legacy_input_gamma_mode(ipp110, is_legacy);
-+}
-+
-+static void set_lut_inc(
-+ struct dce110_ipp *ipp110,
-+ uint8_t inc,
-+ bool is_float,
-+ bool is_signed)
-+{
-+ const uint32_t addr = DCP_REG(mmDC_LUT_CONTROL);
-+
-+ uint32_t value = dal_read_reg(ipp110->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ inc,
-+ DC_LUT_CONTROL,
-+ DC_LUT_INC_R);
-+
-+ set_reg_field_value(
-+ value,
-+ inc,
-+ DC_LUT_CONTROL,
-+ DC_LUT_INC_G);
-+
-+ set_reg_field_value(
-+ value,
-+ inc,
-+ DC_LUT_CONTROL,
-+ DC_LUT_INC_B);
-+
-+ set_reg_field_value(
-+ value,
-+ is_float,
-+ DC_LUT_CONTROL,
-+ DC_LUT_DATA_R_FLOAT_POINT_EN);
-+
-+ set_reg_field_value(
-+ value,
-+ is_float,
-+ DC_LUT_CONTROL,
-+ DC_LUT_DATA_G_FLOAT_POINT_EN);
-+
-+ set_reg_field_value(
-+ value,
-+ is_float,
-+ DC_LUT_CONTROL,
-+ DC_LUT_DATA_B_FLOAT_POINT_EN);
-+
-+ set_reg_field_value(
-+ value,
-+ is_signed,
-+ DC_LUT_CONTROL,
-+ DC_LUT_DATA_R_SIGNED_EN);
-+
-+ set_reg_field_value(
-+ value,
-+ is_signed,
-+ DC_LUT_CONTROL,
-+ DC_LUT_DATA_G_SIGNED_EN);
-+
-+ set_reg_field_value(
-+ value,
-+ is_signed,
-+ DC_LUT_CONTROL,
-+ DC_LUT_DATA_B_SIGNED_EN);
-+
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+}
-+
-+static void select_lut(struct dce110_ipp *ipp110)
-+{
-+ uint32_t value = 0;
-+
-+ set_lut_inc(ipp110, 0, false, false);
-+
-+ {
-+ const uint32_t addr = DCP_REG(mmDC_LUT_WRITE_EN_MASK);
-+
-+ value = dal_read_reg(ipp110->base.ctx, addr);
-+
-+ /* enable all */
-+ set_reg_field_value(
-+ value,
-+ 0x7,
-+ DC_LUT_WRITE_EN_MASK,
-+ DC_LUT_WRITE_EN_MASK);
-+
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+ }
-+
-+ {
-+ const uint32_t addr = DCP_REG(mmDC_LUT_RW_MODE);
-+
-+ value = dal_read_reg(ipp110->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_LUT_RW_MODE,
-+ DC_LUT_RW_MODE);
-+
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+ }
-+
-+ {
-+ const uint32_t addr = DCP_REG(mmDC_LUT_CONTROL);
-+
-+ value = dal_read_reg(ipp110->base.ctx, addr);
-+
-+ /* 00 - new u0.12 */
-+ set_reg_field_value(
-+ value,
-+ 3,
-+ DC_LUT_CONTROL,
-+ DC_LUT_DATA_R_FORMAT);
-+
-+ set_reg_field_value(
-+ value,
-+ 3,
-+ DC_LUT_CONTROL,
-+ DC_LUT_DATA_G_FORMAT);
-+
-+ set_reg_field_value(
-+ value,
-+ 3,
-+ DC_LUT_CONTROL,
-+ DC_LUT_DATA_B_FORMAT);
-+
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+ }
-+
-+ {
-+ const uint32_t addr = DCP_REG(mmDC_LUT_RW_INDEX);
-+
-+ value = dal_read_reg(ipp110->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_LUT_RW_INDEX,
-+ DC_LUT_RW_INDEX);
-+
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+ }
-+}
-+
-+static void program_black_offsets(
-+ struct dce110_ipp *ipp110,
-+ struct dev_c_lut16 *offset)
-+{
-+ dal_write_reg(ipp110->base.ctx,
-+ DCP_REG(mmDC_LUT_BLACK_OFFSET_RED),
-+ offset->red);
-+ dal_write_reg(ipp110->base.ctx,
-+ DCP_REG(mmDC_LUT_BLACK_OFFSET_GREEN),
-+ offset->green);
-+ dal_write_reg(ipp110->base.ctx,
-+ DCP_REG(mmDC_LUT_BLACK_OFFSET_BLUE),
-+ offset->blue);
-+}
-+
-+static void program_white_offsets(
-+ struct dce110_ipp *ipp110,
-+ struct dev_c_lut16 *offset)
-+{
-+ dal_write_reg(ipp110->base.ctx,
-+ DCP_REG(mmDC_LUT_WHITE_OFFSET_RED),
-+ offset->red);
-+ dal_write_reg(ipp110->base.ctx,
-+ DCP_REG(mmDC_LUT_WHITE_OFFSET_GREEN),
-+ offset->green);
-+ dal_write_reg(ipp110->base.ctx,
-+ DCP_REG(mmDC_LUT_WHITE_OFFSET_BLUE),
-+ offset->blue);
-+}
-+
-+static void program_black_white_offset(
-+ struct dce110_ipp *ipp110,
-+ enum pixel_format surface_pixel_format)
-+{
-+ struct dev_c_lut16 black_offset;
-+ struct dev_c_lut16 white_offset;
-+
-+ /* get black offset */
-+
-+ switch (surface_pixel_format) {
-+ case PIXEL_FORMAT_FP16:
-+ /* sRGB gamut, [0.0...1.0] */
-+ black_offset.red = 0;
-+ black_offset.green = 0;
-+ black_offset.blue = 0;
-+ break;
-+
-+ case PIXEL_FORMAT_ARGB2101010_XRBIAS:
-+ /* [-1.0...3.0] */
-+ black_offset.red = 0x100;
-+ black_offset.green = 0x100;
-+ black_offset.blue = 0x100;
-+ break;
-+
-+ default:
-+ black_offset.red = 0;
-+ black_offset.green = 0;
-+ black_offset.blue = 0;
-+ }
-+
-+ /* get white offset */
-+
-+ switch (surface_pixel_format) {
-+ case PIXEL_FORMAT_FP16:
-+ white_offset.red = 0x3BFF;
-+ white_offset.green = 0x3BFF;
-+ white_offset.blue = 0x3BFF;
-+ break;
-+
-+ case PIXEL_FORMAT_ARGB2101010_XRBIAS:
-+ white_offset.red = 0x37E;
-+ white_offset.green = 0x37E;
-+ white_offset.blue = 0x37E;
-+ break;
-+
-+ case PIXEL_FORMAT_ARGB8888:
-+ white_offset.red = 0xFF;
-+ white_offset.green = 0xFF;
-+ white_offset.blue = 0xFF;
-+ break;
-+
-+ default:
-+ white_offset.red = 0x3FF;
-+ white_offset.green = 0x3FF;
-+ white_offset.blue = 0x3FF;
-+ }
-+
-+ program_black_offsets(ipp110, &black_offset);
-+ program_white_offsets(ipp110, &white_offset);
-+}
-+
-+static void program_lut_gamma(
-+ struct dce110_ipp *ipp110,
-+ const struct dev_c_lut16 *gamma,
-+ const struct gamma_parameters *params)
-+{
-+ uint32_t i = 0;
-+ uint32_t value = 0;
-+ uint32_t addr;
-+
-+ {
-+ uint8_t max_tries = 10;
-+ uint8_t counter = 0;
-+
-+ /* Power on LUT memory */
-+ value = dal_read_reg(
-+ ipp110->base.ctx, DCP_REG(mmDCFE_MEM_PWR_CTRL));
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DCFE_MEM_PWR_CTRL,
-+ DCP_REGAMMA_MEM_PWR_DIS);
-+
-+ dal_write_reg(
-+ ipp110->base.ctx, DCP_REG(mmDCFE_MEM_PWR_CTRL), value);
-+
-+ while (counter < max_tries) {
-+ value =
-+ dal_read_reg(
-+ ipp110->base.ctx,
-+ DCP_REG(mmDCFE_MEM_PWR_STATUS));
-+
-+ if (get_reg_field_value(
-+ value,
-+ DCFE_MEM_PWR_STATUS,
-+ DCP_REGAMMA_MEM_PWR_STATE) == 0)
-+ break;
-+
-+ ++counter;
-+ }
-+
-+ if (counter == max_tries) {
-+ dal_logger_write(ipp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: regamma lut was not powered on in a timely manner, programming still proceeds\n",
-+ __func__);
-+ }
-+ }
-+
-+ program_black_white_offset(ipp110, params->surface_pixel_format);
-+
-+ select_lut(ipp110);
-+
-+ if (params->surface_pixel_format == PIXEL_FORMAT_INDEX8) {
-+ addr = DCP_REG(mmDC_LUT_SEQ_COLOR);
-+
-+ do {
-+ struct dev_c_lut *index =
-+ ipp110->saved_palette + i;
-+
-+ set_reg_field_value(
-+ value,
-+ gamma[index->red].red,
-+ DC_LUT_SEQ_COLOR,
-+ DC_LUT_SEQ_COLOR);
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+
-+
-+ set_reg_field_value(
-+ value,
-+ gamma[index->green].green,
-+ DC_LUT_SEQ_COLOR,
-+ DC_LUT_SEQ_COLOR);
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+
-+
-+ set_reg_field_value(
-+ value,
-+ gamma[index->blue].blue,
-+ DC_LUT_SEQ_COLOR,
-+ DC_LUT_SEQ_COLOR);
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+
-+ ++i;
-+ } while (i != RGB_256X3X16);
-+ } else {
-+ addr = DCP_REG(mmDC_LUT_SEQ_COLOR);
-+
-+ do {
-+ set_reg_field_value(
-+ value,
-+ gamma[i].red,
-+ DC_LUT_SEQ_COLOR,
-+ DC_LUT_SEQ_COLOR);
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+
-+
-+ set_reg_field_value(
-+ value,
-+ gamma[i].green,
-+ DC_LUT_SEQ_COLOR,
-+ DC_LUT_SEQ_COLOR);
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+
-+
-+ set_reg_field_value(
-+ value,
-+ gamma[i].blue,
-+ DC_LUT_SEQ_COLOR,
-+ DC_LUT_SEQ_COLOR);
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+
-+ ++i;
-+ } while (i != RGB_256X3X16);
-+ }
-+
-+ /* we are done with DCP LUT memory; re-enable low power mode */
-+ value = dal_read_reg(ipp110->base.ctx, DCP_REG(mmDCFE_MEM_PWR_CTRL));
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DCFE_MEM_PWR_CTRL,
-+ DCP_REGAMMA_MEM_PWR_DIS);
-+
-+ dal_write_reg(ipp110->base.ctx, DCP_REG(mmDCFE_MEM_PWR_CTRL), value);
-+}
-+
-+static void program_prescale(
-+ struct dce110_ipp *ipp110,
-+ enum pixel_format pixel_format)
-+{
-+ uint32_t prescale_control;
-+ uint32_t prescale_values_grph_r = 0;
-+ uint32_t prescale_values_grph_g = 0;
-+ uint32_t prescale_values_grph_b = 0;
-+
-+ uint32_t prescale_num;
-+ uint32_t prescale_denom = 1;
-+ uint16_t prescale_hw;
-+ uint32_t bias_num = 0;
-+ uint32_t bias_denom = 1;
-+ uint16_t bias_hw;
-+
-+ const uint32_t addr_control = DCP_REG(mmPRESCALE_GRPH_CONTROL);
-+
-+ prescale_control = dal_read_reg(ipp110->base.ctx, addr_control);
-+
-+ set_reg_field_value(
-+ prescale_control,
-+ 0,
-+ PRESCALE_GRPH_CONTROL,
-+ GRPH_PRESCALE_BYPASS);
-+
-+ switch (pixel_format) {
-+ case PIXEL_FORMAT_RGB565:
-+ prescale_num = 64;
-+ prescale_denom = 63;
-+ break;
-+
-+ case PIXEL_FORMAT_ARGB8888:
-+ /* This function should only be called when using regamma
-+ * and bypassing legacy INPUT GAMMA LUT (function name is
-+ * misleading)
-+ */
-+ prescale_num = 256;
-+ prescale_denom = 255;
-+ break;
-+
-+ case PIXEL_FORMAT_ARGB2101010:
-+ prescale_num = 1024;
-+ prescale_denom = 1023;
-+ break;
-+
-+ case PIXEL_FORMAT_ARGB2101010_XRBIAS:
-+ prescale_num = 1024;
-+ prescale_denom = 510;
-+ bias_num = 384;
-+ bias_denom = 1024;
-+ break;
-+
-+ case PIXEL_FORMAT_FP16:
-+ prescale_num = 1;
-+ break;
-+
-+ default:
-+ prescale_num = 1;
-+
-+ set_reg_field_value(
-+ prescale_control,
-+ 1,
-+ PRESCALE_GRPH_CONTROL,
-+ GRPH_PRESCALE_BYPASS);
-+ }
-+
-+ prescale_hw = fixed_point_to_int_frac(
-+ dal_fixed31_32_from_fraction(prescale_num, prescale_denom),
-+ 2, 13);
-+
-+ bias_hw = fixed_point_to_int_frac(
-+ dal_fixed31_32_from_fraction(bias_num, bias_denom),
-+ 2, 13);
-+
-+
-+ set_reg_field_value(
-+ prescale_values_grph_r,
-+ prescale_hw,
-+ PRESCALE_VALUES_GRPH_R,
-+ GRPH_PRESCALE_SCALE_R);
-+
-+ set_reg_field_value(
-+ prescale_values_grph_r,
-+ bias_hw,
-+ PRESCALE_VALUES_GRPH_R,
-+ GRPH_PRESCALE_BIAS_R);
-+
-+
-+ set_reg_field_value(
-+ prescale_values_grph_g,
-+ prescale_hw,
-+ PRESCALE_VALUES_GRPH_G,
-+ GRPH_PRESCALE_SCALE_G);
-+
-+ set_reg_field_value(
-+ prescale_values_grph_g,
-+ bias_hw,
-+ PRESCALE_VALUES_GRPH_G,
-+ GRPH_PRESCALE_BIAS_G);
-+
-+
-+ set_reg_field_value(
-+ prescale_values_grph_b,
-+ prescale_hw,
-+ PRESCALE_VALUES_GRPH_B,
-+ GRPH_PRESCALE_SCALE_B);
-+
-+ set_reg_field_value(
-+ prescale_values_grph_b,
-+ bias_hw,
-+ PRESCALE_VALUES_GRPH_B,
-+ GRPH_PRESCALE_BIAS_B);
-+
-+ dal_write_reg(ipp110->base.ctx,
-+ addr_control, prescale_control);
-+
-+ {
-+ dal_write_reg(ipp110->base.ctx,
-+ DCP_REG(mmPRESCALE_VALUES_GRPH_R),
-+ prescale_values_grph_r);
-+ }
-+
-+ {
-+ dal_write_reg(ipp110->base.ctx,
-+ DCP_REG(mmPRESCALE_VALUES_GRPH_G),
-+ prescale_values_grph_g);
-+ }
-+
-+ {
-+ dal_write_reg(ipp110->base.ctx,
-+ DCP_REG(mmPRESCALE_VALUES_GRPH_B),
-+ prescale_values_grph_b);
-+ }
-+}
-+
-+static void set_legacy_input_gamma_mode(
-+ struct dce110_ipp *ipp110,
-+ bool is_legacy)
-+{
-+ const uint32_t addr = DCP_REG(mmINPUT_GAMMA_CONTROL);
-+ uint32_t value = dal_read_reg(ipp110->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ !is_legacy,
-+ INPUT_GAMMA_CONTROL,
-+ GRPH_INPUT_GAMMA_MODE);
-+
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+}
-+
-+static bool set_legacy_input_gamma_ramp_rgb256x3x16(
-+ struct dce110_ipp *ipp110,
-+ const struct gamma_ramp *gamma_ramp,
-+ const struct gamma_parameters *params)
-+{
-+ struct dev_c_lut16 *gamma16 =
-+ dc_service_alloc(
-+ ipp110->base.ctx,
-+ sizeof(struct dev_c_lut16) * MAX_INPUT_LUT_ENTRY);
-+
-+ if (!gamma16)
-+ return false;
-+
-+ convert_256_lut_entries_to_gxo_format(
-+ &gamma_ramp->gamma_ramp_rgb256x3x16, gamma16);
-+
-+ if ((params->surface_pixel_format != PIXEL_FORMAT_ARGB2101010) &&
-+ (params->surface_pixel_format !=
-+ PIXEL_FORMAT_ARGB2101010_XRBIAS) &&
-+ (params->surface_pixel_format != PIXEL_FORMAT_FP16)) {
-+ program_lut_gamma(ipp110, gamma16, params);
-+ dc_service_free(ipp110->base.ctx, gamma16);
-+ return true;
-+ }
-+
-+ /* TODO process DirectX-specific formats*/
-+ dc_service_free(ipp110->base.ctx, gamma16);
-+ return false;
-+}
-+
-+static bool set_legacy_input_gamma_ramp_dxgi1(
-+ struct dce110_ipp *ipp110,
-+ const struct gamma_ramp *gamma_ramp,
-+ const struct gamma_parameters *params)
-+{
-+ struct dev_c_lut16 *gamma16 =
-+ dc_service_alloc(
-+ ipp110->base.ctx,
-+ sizeof(struct dev_c_lut16) * MAX_INPUT_LUT_ENTRY);
-+
-+ if (!gamma16)
-+ return false;
-+
-+ convert_udx_gamma_entries_to_gxo_format(
-+ &gamma_ramp->gamma_ramp_dxgi1, gamma16);
-+
-+ if ((params->surface_pixel_format != PIXEL_FORMAT_ARGB2101010) &&
-+ (params->surface_pixel_format !=
-+ PIXEL_FORMAT_ARGB2101010_XRBIAS) &&
-+ (params->surface_pixel_format != PIXEL_FORMAT_FP16)) {
-+ program_lut_gamma(ipp110, gamma16, params);
-+ dc_service_free(ipp110->base.ctx, gamma16);
-+ return true;
-+ }
-+
-+ /* TODO process DirectX-specific formats*/
-+ dc_service_free(ipp110->base.ctx, gamma16);
-+ return false;
-+}
-+
-+static bool set_default_gamma(
-+ struct dce110_ipp *ipp110,
-+ enum pixel_format surface_pixel_format)
-+{
-+ uint32_t i;
-+
-+ struct dev_c_lut16 *gamma16 = NULL;
-+ struct gamma_parameters *params = NULL;
-+
-+ gamma16 = dc_service_alloc(
-+ ipp110->base.ctx,
-+ sizeof(struct dev_c_lut16) * MAX_INPUT_LUT_ENTRY);
-+
-+ if (!gamma16)
-+ return false;
-+
-+ params = dc_service_alloc(ipp110->base.ctx, sizeof(*params));
-+
-+ if (!params) {
-+ dc_service_free(ipp110->base.ctx, gamma16);
-+ return false;
-+ }
-+
-+ for (i = 0; i < MAX_INPUT_LUT_ENTRY; i++) {
-+ gamma16[i].red = gamma16[i].green =
-+ gamma16[i].blue = (uint16_t) (i << 8);
-+ }
-+
-+ params->surface_pixel_format = surface_pixel_format;
-+ params->regamma_adjust_type = GRAPHICS_REGAMMA_ADJUST_HW;
-+ params->degamma_adjust_type = GRAPHICS_DEGAMMA_ADJUST_HW;
-+ params->selected_gamma_lut = GRAPHICS_GAMMA_LUT_REGAMMA;
-+ params->disable_adjustments = false;
-+
-+ params->regamma.features.value = 0;
-+
-+ params->regamma.features.bits.GAMMA_RAMP_ARRAY = 0;
-+ params->regamma.features.bits.GRAPHICS_DEGAMMA_SRGB = 1;
-+ params->regamma.features.bits.OVERLAY_DEGAMMA_SRGB = 1;
-+
-+ for (i = 0; i < 3; i++) {
-+ params->regamma.gamma_coeff.a0[i] = 31308;
-+ params->regamma.gamma_coeff.a1[i] = 12920;
-+ params->regamma.gamma_coeff.a2[i] = 55;
-+ params->regamma.gamma_coeff.a3[i] = 55;
-+ params->regamma.gamma_coeff.gamma[i] = 2400;
-+
-+ }
-+
-+ program_lut_gamma(ipp110, gamma16, params);
-+
-+ dc_service_free(ipp110->base.ctx, gamma16);
-+ dc_service_free(ipp110->base.ctx, params);
-+
-+ return true;
-+}
-+
-+static void set_degamma(
-+ struct dce110_ipp *ipp110,
-+ const struct gamma_parameters *params,
-+ bool force_bypass)
-+{
-+ uint32_t value;
-+ const uint32_t addr = DCP_REG(mmDEGAMMA_CONTROL);
-+ uint32_t degamma_type =
-+ params->regamma.features.bits.GRAPHICS_DEGAMMA_SRGB == 1 ?
-+ 1 : 2;
-+
-+ value = dal_read_reg(ipp110->base.ctx, addr);
-+
-+ /* if by pass - no degamma
-+ * when legacy and regamma LUT's we do degamma */
-+ if (params->degamma_adjust_type == GRAPHICS_DEGAMMA_ADJUST_BYPASS ||
-+ (params->surface_pixel_format == PIXEL_FORMAT_FP16 &&
-+ params->selected_gamma_lut ==
-+ GRAPHICS_GAMMA_LUT_REGAMMA))
-+ degamma_type = 0;
-+
-+ if (force_bypass)
-+ degamma_type = 0;
-+
-+ set_reg_field_value(
-+ value,
-+ degamma_type,
-+ DEGAMMA_CONTROL,
-+ GRPH_DEGAMMA_MODE);
-+
-+ set_reg_field_value(
-+ value,
-+ degamma_type,
-+ DEGAMMA_CONTROL,
-+ CURSOR_DEGAMMA_MODE);
-+
-+ set_reg_field_value(
-+ value,
-+ degamma_type,
-+ DEGAMMA_CONTROL,
-+ CURSOR2_DEGAMMA_MODE);
-+
-+ dal_write_reg(ipp110->base.ctx, addr, value);
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.c
-new file mode 100644
-index 0000000..0297bd3
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.c
-@@ -0,0 +1,2049 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "core_types.h"
-+#include "link_encoder_types.h"
-+#include "dce110_link_encoder.h"
-+#include "i2caux_interface.h"
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+#include "dce/dce_11_0_enum.h"
-+
-+#define DELAY_AFTER_PIXEL_FORMAT_CHANGE 0 /* ms */
-+/* For current ASICs pixel clock - 600MHz */
-+#define MAX_ENCODER_CLK 600000
-+
-+#define DCE11_UNIPHY_MAX_PIXEL_CLK_IN_KHZ 600000
-+
-+#define DEFAULT_AUX_MAX_DATA_SIZE 16
-+#define AUX_MAX_DEFER_WRITE_RETRY 20
-+/*
-+ * @brief
-+ * Trigger Source Select
-+ * ASIC-dependent, actual values for register programming
-+ */
-+#define DCE110_DIG_FE_SOURCE_SELECT_INVALID 0x0
-+#define DCE110_DIG_FE_SOURCE_SELECT_DIGA 0x1
-+#define DCE110_DIG_FE_SOURCE_SELECT_DIGB 0x2
-+#define DCE110_DIG_FE_SOURCE_SELECT_DIGC 0x4
-+
-+/* all values are in milliseconds */
-+/* For eDP, after power-up/power/down,
-+ * 300/500 msec max. delay from LCDVCC to black video generation */
-+#define PANEL_POWER_UP_TIMEOUT 300
-+#define PANEL_POWER_DOWN_TIMEOUT 500
-+#define HPD_CHECK_INTERVAL 10
-+
-+/* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */
-+#define TMDS_MIN_PIXEL_CLOCK 25000
-+/* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */
-+#define TMDS_MAX_PIXEL_CLOCK 165000
-+/* For current ASICs pixel clock - 600MHz */
-+#define MAX_ENCODER_CLOCK 600000
-+
-+enum {
-+ DP_MST_UPDATE_MAX_RETRY = 50
-+};
-+
-+#ifndef mmDP_DPHY_INTERNAL_CTRL
-+ #define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
-+ #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7
-+ #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x4ba7
-+ #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x4ca7
-+ #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x4da7
-+ #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x4ea7
-+ #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4fa7
-+ #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x54a7
-+ #define mmDP7_DP_DPHY_INTERNAL_CTRL 0x56a7
-+ #define mmDP8_DP_DPHY_INTERNAL_CTRL 0x57a7
-+#endif
-+
-+
-+static const uint32_t fe_engine_offsets[] = {
-+ mmDIG0_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+ mmDIG1_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+ mmDIG2_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+};
-+
-+
-+static enum transmitter translate_encoder_to_transmitter(
-+ struct graphics_object_id encoder)
-+{
-+ switch (encoder.id) {
-+ case ENCODER_ID_INTERNAL_UNIPHY:
-+ switch (encoder.enum_id) {
-+ case ENUM_ID_1:
-+ return TRANSMITTER_UNIPHY_A;
-+ case ENUM_ID_2:
-+ return TRANSMITTER_UNIPHY_B;
-+ default:
-+ return TRANSMITTER_UNKNOWN;
-+ }
-+ break;
-+ case ENCODER_ID_INTERNAL_UNIPHY1:
-+ switch (encoder.enum_id) {
-+ case ENUM_ID_1:
-+ return TRANSMITTER_UNIPHY_C;
-+ case ENUM_ID_2:
-+ return TRANSMITTER_UNIPHY_D;
-+ default:
-+ return TRANSMITTER_UNKNOWN;
-+ }
-+ break;
-+ case ENCODER_ID_INTERNAL_UNIPHY2:
-+ switch (encoder.enum_id) {
-+ case ENUM_ID_1:
-+ return TRANSMITTER_UNIPHY_E;
-+ case ENUM_ID_2:
-+ return TRANSMITTER_UNIPHY_F;
-+ default:
-+ return TRANSMITTER_UNKNOWN;
-+ }
-+ break;
-+ case ENCODER_ID_INTERNAL_UNIPHY3:
-+ switch (encoder.enum_id) {
-+ case ENUM_ID_1:
-+ return TRANSMITTER_UNIPHY_G;
-+ default:
-+ return TRANSMITTER_UNKNOWN;
-+ }
-+ break;
-+ case ENCODER_ID_EXTERNAL_NUTMEG:
-+ switch (encoder.enum_id) {
-+ case ENUM_ID_1:
-+ return TRANSMITTER_NUTMEG_CRT;
-+ default:
-+ return TRANSMITTER_UNKNOWN;
-+ }
-+ break;
-+ case ENCODER_ID_EXTERNAL_TRAVIS:
-+ switch (encoder.enum_id) {
-+ case ENUM_ID_1:
-+ return TRANSMITTER_TRAVIS_CRT;
-+ case ENUM_ID_2:
-+ return TRANSMITTER_TRAVIS_LCD;
-+ default:
-+ return TRANSMITTER_UNKNOWN;
-+ }
-+ break;
-+ default:
-+ return TRANSMITTER_UNKNOWN;
-+ }
-+}
-+
-+static void enable_phy_bypass_mode(
-+ struct dc_context *ctx,
-+ const int32_t be_addr_offset,
-+ bool enable)
-+{
-+ /* This register resides in DP back end block;
-+ * transmitter is used for the offset */
-+
-+ const uint32_t addr = mmDP_DPHY_CNTL + be_addr_offset;
-+
-+ uint32_t value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(value, enable, DP_DPHY_CNTL, DPHY_BYPASS);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+static void disable_prbs_symbols(
-+ struct dc_context *ctx,
-+ const int32_t be_addr_offset,
-+ bool disable)
-+{
-+ /* This register resides in DP back end block;
-+ * transmitter is used for the offset */
-+
-+ const uint32_t addr = mmDP_DPHY_CNTL + be_addr_offset;
-+
-+ uint32_t value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(value, disable,
-+ DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE0);
-+
-+ set_reg_field_value(value, disable,
-+ DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE1);
-+
-+ set_reg_field_value(value, disable,
-+ DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE2);
-+
-+ set_reg_field_value(value, disable,
-+ DP_DPHY_CNTL, DPHY_ATEST_SEL_LANE3);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+static void disable_prbs_mode(
-+ struct dc_context *ctx,
-+ const int32_t be_addr_offset)
-+{
-+ /* This register resides in DP back end block;
-+ * transmitter is used for the offset */
-+
-+ const uint32_t addr = mmDP_DPHY_PRBS_CNTL + be_addr_offset;
-+ uint32_t value;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(value, 0, DP_DPHY_PRBS_CNTL, DPHY_PRBS_EN);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+static void program_pattern_symbols(
-+ struct dc_context *ctx,
-+ const int32_t be_addr_offset,
-+ uint16_t pattern_symbols[8])
-+{
-+ uint32_t addr;
-+ uint32_t value;
-+
-+ /* This register resides in DP back end block;
-+ * transmitter is used for the offset */
-+
-+ addr = mmDP_DPHY_SYM0 + be_addr_offset;
-+
-+ value = 0;
-+ set_reg_field_value(value, pattern_symbols[0],
-+ DP_DPHY_SYM0, DPHY_SYM1);
-+ set_reg_field_value(value, pattern_symbols[1],
-+ DP_DPHY_SYM0, DPHY_SYM2);
-+ set_reg_field_value(value, pattern_symbols[2],
-+ DP_DPHY_SYM0, DPHY_SYM3);
-+ dal_write_reg(ctx, addr, value);
-+
-+ /* This register resides in DP back end block;
-+ * transmitter is used for the offset */
-+
-+ addr = mmDP_DPHY_SYM1 + be_addr_offset;
-+
-+ value = 0;
-+ set_reg_field_value(value, pattern_symbols[3],
-+ DP_DPHY_SYM1, DPHY_SYM4);
-+ set_reg_field_value(value, pattern_symbols[4],
-+ DP_DPHY_SYM1, DPHY_SYM5);
-+ set_reg_field_value(value, pattern_symbols[5],
-+ DP_DPHY_SYM1, DPHY_SYM6);
-+ dal_write_reg(ctx, addr, value);
-+
-+ /* This register resides in DP back end block;
-+ * transmitter is used for the offset */
-+ addr = mmDP_DPHY_SYM2 + be_addr_offset;
-+ value = 0;
-+ set_reg_field_value(value, pattern_symbols[6],
-+ DP_DPHY_SYM2, DPHY_SYM7);
-+ set_reg_field_value(value, pattern_symbols[6],
-+ DP_DPHY_SYM2, DPHY_SYM8);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+static void set_dp_phy_pattern_d102(
-+ struct dc_context *ctx,
-+ const int32_t be_addr_offset)
-+{
-+ /* Disable PHY Bypass mode to setup the test pattern */
-+
-+ enable_phy_bypass_mode(ctx, be_addr_offset, false);
-+
-+ /* For 10-bit PRBS or debug symbols
-+ * please use the following sequence: */
-+
-+ /* Enable debug symbols on the lanes */
-+
-+ disable_prbs_symbols(ctx, be_addr_offset, true);
-+
-+ /* Disable PRBS mode,
-+ * make sure DPHY_PRBS_CNTL.DPHY_PRBS_EN=0 */
-+
-+ disable_prbs_mode(ctx, be_addr_offset);
-+
-+ /* Program debug symbols to be output */
-+ {
-+ uint16_t pattern_symbols[8] = {
-+ 0x2AA, 0x2AA, 0x2AA, 0x2AA,
-+ 0x2AA, 0x2AA, 0x2AA, 0x2AA
-+ };
-+
-+ program_pattern_symbols(ctx,
-+ be_addr_offset, pattern_symbols);
-+ }
-+
-+ /* Enable phy bypass mode to enable the test pattern */
-+
-+ enable_phy_bypass_mode(ctx, be_addr_offset, true);
-+}
-+
-+static void set_link_training_complete(
-+ struct dc_context *ctx,
-+ const int32_t be_addr_offset,
-+ bool complete)
-+{
-+ /* This register resides in DP back end block;
-+ * transmitter is used for the offset */
-+
-+ const uint32_t addr = mmDP_LINK_CNTL + be_addr_offset;
-+
-+ uint32_t value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(value, complete,
-+ DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+static void set_dp_phy_pattern_training_pattern(
-+ struct dc_context *ctx,
-+ const int32_t be_addr_offset,
-+ uint32_t index)
-+{
-+ /* Write Training Pattern */
-+
-+ dal_write_reg(ctx,
-+ mmDP_DPHY_TRAINING_PATTERN_SEL + be_addr_offset, index);
-+
-+ /* Set HW Register Training Complete to false */
-+
-+ set_link_training_complete(ctx, be_addr_offset, false);
-+
-+ /* Disable PHY Bypass mode to output Training Pattern */
-+
-+ enable_phy_bypass_mode(ctx, be_addr_offset, false);
-+
-+ /* Disable PRBS mode,
-+ * make sure DPHY_PRBS_CNTL.DPHY_PRBS_EN=0 */
-+
-+ disable_prbs_mode(ctx, be_addr_offset);
-+}
-+
-+static void set_dp_phy_pattern_symbol_error(
-+ struct dc_context *ctx,
-+ const int32_t addr_offset)
-+{
-+ /* Disable PHY Bypass mode to setup the test pattern */
-+
-+ enable_phy_bypass_mode(ctx, addr_offset, false);
-+
-+ /* program correct panel mode*/
-+ {
-+ const uint32_t addr = mmDP_DPHY_INTERNAL_CTRL + addr_offset;
-+ uint32_t value = 0x0;
-+ dal_write_reg(ctx, addr, value);
-+ }
-+
-+ /* A PRBS23 pattern is used for most DP electrical measurements. */
-+
-+ /* Enable PRBS symbols on the lanes */
-+
-+ disable_prbs_symbols(ctx, addr_offset, false);
-+
-+ /* For PRBS23 Set bit DPHY_PRBS_SEL=1 and Set bit DPHY_PRBS_EN=1 */
-+ {
-+ const uint32_t addr = mmDP_DPHY_PRBS_CNTL + addr_offset;
-+ uint32_t value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(value, 1,
-+ DP_DPHY_PRBS_CNTL, DPHY_PRBS_SEL);
-+ set_reg_field_value(value, 1,
-+ DP_DPHY_PRBS_CNTL, DPHY_PRBS_EN);
-+ dal_write_reg(ctx, addr, value);
-+ }
-+
-+ /* Enable phy bypass mode to enable the test pattern */
-+
-+ enable_phy_bypass_mode(ctx, addr_offset, true);
-+}
-+
-+static void set_dp_phy_pattern_prbs7(
-+ struct dc_context *ctx,
-+ const int32_t addr_offset)
-+{
-+ /* Disable PHY Bypass mode to setup the test pattern */
-+
-+ enable_phy_bypass_mode(ctx, addr_offset, false);
-+
-+ /* A PRBS7 pattern is used for most DP electrical measurements. */
-+
-+ /* Enable PRBS symbols on the lanes */
-+
-+ disable_prbs_symbols(ctx, addr_offset, false);
-+
-+ /* For PRBS7 Set bit DPHY_PRBS_SEL=0 and Set bit DPHY_PRBS_EN=1 */
-+ {
-+ const uint32_t addr = mmDP_DPHY_PRBS_CNTL + addr_offset;
-+
-+ uint32_t value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(value, 0,
-+ DP_DPHY_PRBS_CNTL, DPHY_PRBS_SEL);
-+
-+ set_reg_field_value(value, 1,
-+ DP_DPHY_PRBS_CNTL, DPHY_PRBS_EN);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+
-+ /* Enable phy bypass mode to enable the test pattern */
-+
-+ enable_phy_bypass_mode(ctx, addr_offset, true);
-+}
-+
-+static void set_dp_phy_pattern_80bit_custom(
-+ struct dc_context *ctx,
-+ const int32_t be_addr_offset,
-+ const uint8_t *pattern)
-+{
-+ /* Disable PHY Bypass mode to setup the test pattern */
-+
-+ enable_phy_bypass_mode(ctx, be_addr_offset, false);
-+
-+ /* Enable debug symbols on the lanes */
-+
-+ disable_prbs_symbols(ctx, be_addr_offset, true);
-+
-+ /* Enable PHY bypass mode to enable the test pattern */
-+ /* TODO is it really needed ? */
-+
-+ enable_phy_bypass_mode(ctx, be_addr_offset, true);
-+
-+ /* Program 80 bit custom pattern */
-+ {
-+ uint16_t pattern_symbols[8];
-+
-+ pattern_symbols[0] =
-+ ((pattern[1] & 0x03) << 8) | pattern[0];
-+ pattern_symbols[1] =
-+ ((pattern[2] & 0x0f) << 6) | ((pattern[1] >> 2) & 0x3f);
-+ pattern_symbols[2] =
-+ ((pattern[3] & 0x3f) << 4) | ((pattern[2] >> 4) & 0x0f);
-+ pattern_symbols[3] =
-+ (pattern[4] << 2) | ((pattern[3] >> 6) & 0x03);
-+ pattern_symbols[4] =
-+ ((pattern[6] & 0x03) << 8) | pattern[5];
-+ pattern_symbols[5] =
-+ ((pattern[7] & 0x0f) << 6) | ((pattern[6] >> 2) & 0x3f);
-+ pattern_symbols[6] =
-+ ((pattern[8] & 0x3f) << 4) | ((pattern[7] >> 4) & 0x0f);
-+ pattern_symbols[7] =
-+ (pattern[9] << 2) | ((pattern[8] >> 6) & 0x03);
-+
-+ program_pattern_symbols(ctx,
-+ be_addr_offset, pattern_symbols);
-+ }
-+
-+ /* Enable phy bypass mode to enable the test pattern */
-+
-+ enable_phy_bypass_mode(ctx, be_addr_offset, true);
-+}
-+
-+void dce110_link_encoder_setup(
-+ struct link_encoder *enc,
-+ enum signal_type signal)
-+{
-+ const uint32_t addr = mmDIG_BE_CNTL + enc->be_engine_offset;
-+ uint32_t value = dal_read_reg(enc->ctx, addr);
-+
-+ switch (signal) {
-+ case SIGNAL_TYPE_EDP:
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ /* DP SST */
-+ set_reg_field_value(value, 0, DIG_BE_CNTL, DIG_MODE);
-+ break;
-+ case SIGNAL_TYPE_LVDS:
-+ /* LVDS */
-+ set_reg_field_value(value, 1, DIG_BE_CNTL, DIG_MODE);
-+ break;
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
-+ case SIGNAL_TYPE_DVI_DUAL_LINK:
-+ /* TMDS-DVI */
-+ set_reg_field_value(value, 2, DIG_BE_CNTL, DIG_MODE);
-+ break;
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ /* TMDS-HDMI */
-+ set_reg_field_value(value, 3, DIG_BE_CNTL, DIG_MODE);
-+ break;
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ /* DP MST */
-+ set_reg_field_value(value, 5, DIG_BE_CNTL, DIG_MODE);
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ /* invalid mode ! */
-+ break;
-+ }
-+
-+ dal_write_reg(enc->ctx, addr, value);
-+}
-+
-+static void set_dp_phy_pattern_hbr2_compliance(
-+ struct link_encoder *enc,
-+ const int32_t be_addr_offset)
-+{
-+ /*const int32_t fe_addr_offset = fe_engine_offsets[param->engine];
-+ const int32_t be_addr_offset = enc->be_engine_offset;*/
-+
-+ uint32_t addr;
-+ uint32_t value;
-+
-+ /* previously there is a register DP_HBR2_EYE_PATTERN
-+ * that is enabled to get the pattern.
-+ * But it does not work with the latest spec change,
-+ * so we are programming the following registers manually.
-+ *
-+ * The following settings have been confirmed
-+ * by Nick Chorney and Sandra Liu */
-+
-+ /* Disable PHY Bypass mode to setup the test pattern */
-+
-+ enable_phy_bypass_mode(enc->ctx, be_addr_offset, false);
-+
-+ /* Setup DIG encoder in DP SST mode */
-+
-+ dce110_link_encoder_setup(enc, SIGNAL_TYPE_DISPLAY_PORT);
-+
-+ /* program correct panel mode*/
-+ {
-+ const uint32_t addr = mmDP_DPHY_INTERNAL_CTRL + be_addr_offset;
-+ uint32_t value = 0x0;
-+ dal_write_reg(enc->ctx, addr, value);
-+ }
-+
-+ /* no vbid after BS (SR)
-+ * DP_LINK_FRAMING_CNTL changed history Sandra Liu
-+ * 11000260 / 11000104 / 110000FC */
-+
-+ /* TODO DP_LINK_FRAMING_CNTL should always use hardware default value
-+ * output except output hbr2_compliance pattern for physical PHY
-+ * measurement. This is not normal usage case. SW should reset this
-+ * register to hardware default value after end use of HBR2 eye
-+ */
-+ BREAK_TO_DEBUGGER();
-+ /* TODO: do we still need this, find out at compliance test
-+ addr = mmDP_LINK_FRAMING_CNTL + fe_addr_offset;
-+
-+ value = dal_read_reg(enc->ctx, addr);
-+
-+ set_reg_field_value(value, 0xFC,
-+ DP_LINK_FRAMING_CNTL, DP_IDLE_BS_INTERVAL);
-+ set_reg_field_value(value, 1,
-+ DP_LINK_FRAMING_CNTL, DP_VBID_DISABLE);
-+ set_reg_field_value(value, 1,
-+ DP_LINK_FRAMING_CNTL, DP_VID_ENHANCED_FRAME_MODE);
-+
-+ dal_write_reg(enc->ctx, addr, value);
-+ */
-+
-+ /*TODO add support for this test pattern
-+ * support_dp_hbr2_eye_pattern
-+ */
-+
-+ /* set link training complete */
-+ set_link_training_complete(enc->ctx, be_addr_offset, true);
-+ /* do not enable video stream */
-+ addr = mmDP_VID_STREAM_CNTL + be_addr_offset;
-+
-+ value = dal_read_reg(enc->ctx, addr);
-+
-+ set_reg_field_value(value, 0, DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE);
-+
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+ /* Disable PHY Bypass mode to setup the test pattern */
-+
-+ enable_phy_bypass_mode(enc->ctx, be_addr_offset, false);
-+}
-+
-+static void set_dp_phy_pattern_passthrough_mode(
-+ struct dc_context *ctx,
-+ const int32_t be_addr_offset,
-+ enum dp_panel_mode panel_mode)
-+{
-+
-+ /* program correct panel mode */
-+ {
-+ const uint32_t addr = mmDP_DPHY_INTERNAL_CTRL + be_addr_offset;
-+
-+ uint32_t value;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ switch (panel_mode) {
-+ case DP_PANEL_MODE_EDP:
-+ value = 0x1;
-+ break;
-+ case DP_PANEL_MODE_SPECIAL:
-+ value = 0x11;
-+ break;
-+ default:
-+ value = 0x0;
-+ break;
-+ }
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+
-+ /* set link training complete */
-+
-+ set_link_training_complete(ctx, be_addr_offset, true);
-+
-+ /* Disable PHY Bypass mode to setup the test pattern */
-+
-+ enable_phy_bypass_mode(ctx, be_addr_offset, false);
-+
-+ /* Disable PRBS mode,
-+ * make sure DPHY_PRBS_CNTL.DPHY_PRBS_EN=0 */
-+
-+ disable_prbs_mode(ctx, be_addr_offset);
-+}
-+
-+static void construct(
-+ struct link_encoder *enc,
-+ const struct encoder_init_data *init_data)
-+{
-+ struct graphics_object_encoder_cap_info enc_cap_info = {0};
-+
-+ enc->ctx = init_data->ctx;
-+ enc->id = init_data->encoder;
-+
-+ enc->hpd_source = init_data->hpd_source;
-+ enc->connector = init_data->connector;
-+ enc->input_signals = SIGNAL_TYPE_ALL;
-+
-+ enc->adapter_service = init_data->adapter_service;
-+
-+ enc->preferred_engine = ENGINE_ID_UNKNOWN;
-+
-+ enc->features.flags.raw = 0;
-+
-+ enc->transmitter = translate_encoder_to_transmitter(
-+ init_data->encoder);
-+
-+ enc->features.flags.bits.IS_AUDIO_CAPABLE = true;
-+
-+ enc->features.max_pixel_clock = DCE11_UNIPHY_MAX_PIXEL_CLK_IN_KHZ;
-+
-+ /* set the flag to indicate whether driver poll the I2C data pin
-+ * while doing the DP sink detect */
-+
-+ if (dal_adapter_service_is_feature_supported(
-+ FEATURE_DP_SINK_DETECT_POLL_DATA_PIN))
-+ enc->features.flags.bits.DP_SINK_DETECT_POLL_DATA_PIN = true;
-+
-+ enc->output_signals =
-+ SIGNAL_TYPE_DVI_SINGLE_LINK |
-+ SIGNAL_TYPE_DVI_DUAL_LINK |
-+ SIGNAL_TYPE_LVDS |
-+ SIGNAL_TYPE_DISPLAY_PORT |
-+ SIGNAL_TYPE_DISPLAY_PORT_MST |
-+ SIGNAL_TYPE_EDP |
-+ SIGNAL_TYPE_HDMI_TYPE_A;
-+
-+ /* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE.
-+ * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY.
-+ * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer
-+ * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS.
-+ * Prefer DIG assignment is decided by board design.
-+ * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design
-+ * and VBIOS will filter out 7 UNIPHY for DCE 8.0.
-+ * By this, adding DIGG should not hurt DCE 8.0.
-+ * This will let DCE 8.1 share DCE 8.0 as much as possible */
-+
-+ switch (enc->transmitter) {
-+ case TRANSMITTER_UNIPHY_A:
-+ enc->preferred_engine = ENGINE_ID_DIGA;
-+ enc->transmitter_offset = 0;
-+ enc->be_engine_offset = 0;
-+ break;
-+ case TRANSMITTER_UNIPHY_B:
-+ enc->preferred_engine = ENGINE_ID_DIGB;
-+
-+ enc->transmitter_offset =
-+ mmBPHYC_UNIPHY1_UNIPHY_TX_CONTROL1 -
-+ mmBPHYC_UNIPHY0_UNIPHY_TX_CONTROL1;
-+ enc->be_engine_offset =
-+ mmDIG1_DIG_BE_CNTL - mmDIG0_DIG_BE_CNTL;
-+ break;
-+ case TRANSMITTER_UNIPHY_C:
-+ enc->preferred_engine = ENGINE_ID_DIGC;
-+ enc->transmitter_offset =
-+ mmBPHYC_UNIPHY2_UNIPHY_TX_CONTROL1 -
-+ mmBPHYC_UNIPHY0_UNIPHY_TX_CONTROL1;
-+ enc->be_engine_offset =
-+ mmDIG2_DIG_BE_CNTL - mmDIG0_DIG_BE_CNTL;
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ enc->preferred_engine = ENGINE_ID_UNKNOWN;
-+ enc->transmitter_offset = 0;
-+ enc->be_engine_offset = 0;
-+ }
-+
-+ dal_logger_write(init_data->ctx->logger,
-+ LOG_MAJOR_I2C_AUX,
-+ LOG_MINOR_I2C_AUX_CFG,
-+ "Using channel: %s [%d]\n",
-+ DECODE_CHANNEL_ID(init_data->channel),
-+ init_data->channel);
-+
-+ switch (init_data->channel) {
-+ case CHANNEL_ID_DDC1:
-+ enc->aux_channel_offset = 0;
-+ break;
-+ case CHANNEL_ID_DDC2:
-+ enc->aux_channel_offset =
-+ mmDP_AUX1_AUX_CONTROL - mmDP_AUX0_AUX_CONTROL;
-+ break;
-+ case CHANNEL_ID_DDC3:
-+ enc->aux_channel_offset =
-+ mmDP_AUX2_AUX_CONTROL - mmDP_AUX0_AUX_CONTROL;
-+ break;
-+ default:
-+ /* check BIOS object table ! */
-+ dal_logger_write(init_data->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_ENCODER,
-+ "%s: Invalid channel ID\n",
-+ __func__);
-+ enc->aux_channel_offset = 0;
-+ }
-+
-+ /* Override features with DCE-specific values */
-+ if (dal_adapter_service_get_encoder_cap_info(enc->adapter_service,
-+ enc->id, &enc_cap_info))
-+ enc->features.flags.bits.IS_HBR2_CAPABLE =
-+ enc_cap_info.dp_hbr2_cap;
-+
-+ /* test pattern 3 support */
-+ enc->features.flags.bits.IS_TPS3_CAPABLE = true;
-+ enc->features.max_deep_color = COLOR_DEPTH_121212;
-+
-+ enc->features.flags.bits.IS_Y_ONLY_CAPABLE =
-+ dal_adapter_service_is_feature_supported(
-+ FEATURE_SUPPORT_DP_Y_ONLY);
-+
-+ enc->features.flags.bits.IS_YCBCR_CAPABLE =
-+ dal_adapter_service_is_feature_supported(
-+ FEATURE_SUPPORT_DP_YUV);
-+}
-+
-+struct link_encoder *dce110_link_encoder_create(
-+ const struct encoder_init_data *init)
-+{
-+ struct link_encoder *enc =
-+ dc_service_alloc(init->ctx, sizeof(struct link_encoder));
-+
-+ if (!enc)
-+ goto enc_create_fail;
-+
-+ construct(enc, init);
-+
-+ return enc;
-+
-+enc_create_fail:
-+ return NULL;
-+}
-+
-+void dce110_link_encoder_destroy(struct link_encoder **enc)
-+{
-+ struct link_encoder *encoder = *enc;
-+ dc_service_free(encoder->ctx, encoder);
-+ *enc = NULL;
-+}
-+
-+void dce110_link_encoder_set_dp_phy_pattern(
-+ struct link_encoder *enc,
-+ const struct encoder_set_dp_phy_pattern_param *param)
-+{
-+ const int32_t offset = enc->be_engine_offset;
-+
-+
-+ switch (param->dp_phy_pattern) {
-+ case DP_TEST_PATTERN_TRAINING_PATTERN1:
-+ set_dp_phy_pattern_training_pattern(enc->ctx,
-+ offset, 0);
-+ break;
-+ case DP_TEST_PATTERN_TRAINING_PATTERN2:
-+ set_dp_phy_pattern_training_pattern(enc->ctx,
-+ offset, 1);
-+ break;
-+ case DP_TEST_PATTERN_TRAINING_PATTERN3:
-+ set_dp_phy_pattern_training_pattern(enc->ctx,
-+ offset, 2);
-+ break;
-+ case DP_TEST_PATTERN_D102:
-+ set_dp_phy_pattern_d102(enc->ctx, offset);
-+ break;
-+ case DP_TEST_PATTERN_SYMBOL_ERROR:
-+ set_dp_phy_pattern_symbol_error(enc->ctx, offset);
-+ break;
-+ case DP_TEST_PATTERN_PRBS7:
-+ set_dp_phy_pattern_prbs7(enc->ctx, offset);
-+ break;
-+ case DP_TEST_PATTERN_80BIT_CUSTOM:
-+ set_dp_phy_pattern_80bit_custom(
-+ enc->ctx,
-+ offset, param->custom_pattern);
-+ break;
-+ case DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE:
-+ set_dp_phy_pattern_hbr2_compliance(
-+ enc, offset);
-+ break;
-+ case DP_TEST_PATTERN_VIDEO_MODE: {
-+ set_dp_phy_pattern_passthrough_mode(
-+ enc->ctx,
-+ offset,
-+ param->dp_panel_mode);
-+ break;
-+ }
-+
-+
-+ default:
-+ /* invalid phy pattern */
-+ ASSERT_CRITICAL(false);
-+ break;
-+ }
-+}
-+
-+enum encoder_result dce110_link_encoder_dp_set_lane_settings(
-+ struct link_encoder *enc,
-+ const struct link_training_settings *link_settings)
-+{
-+ union dpcd_training_lane_set training_lane_set = { { 0 } };
-+
-+ int32_t lane = 0;
-+
-+ struct bp_transmitter_control cntl = { 0 };
-+
-+ if (!link_settings) {
-+ BREAK_TO_DEBUGGER();
-+ return ENCODER_RESULT_ERROR;
-+ }
-+
-+ cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS;
-+ cntl.transmitter = enc->transmitter;
-+ cntl.connector_obj_id = enc->connector;
-+ cntl.lanes_number = link_settings->link_settings.lane_count;
-+ cntl.hpd_sel = enc->hpd_source;
-+ cntl.pixel_clock = link_settings->link_settings.link_rate *
-+ LINK_RATE_REF_FREQ_IN_KHZ;
-+
-+ for (lane = 0; lane < link_settings->link_settings.lane_count; ++lane) {
-+ /* translate lane settings */
-+
-+ training_lane_set.bits.VOLTAGE_SWING_SET =
-+ link_settings->lane_settings[lane].VOLTAGE_SWING;
-+ training_lane_set.bits.PRE_EMPHASIS_SET =
-+ link_settings->lane_settings[lane].PRE_EMPHASIS;
-+
-+ /* post cursor 2 setting only applies to HBR2 link rate */
-+ if (link_settings->link_settings.link_rate == LINK_RATE_HIGH2) {
-+ /* this is passed to VBIOS
-+ * to program post cursor 2 level */
-+
-+ training_lane_set.bits.POST_CURSOR2_SET =
-+ link_settings->lane_settings[lane].POST_CURSOR2;
-+ }
-+
-+ cntl.lane_select = lane;
-+ cntl.lane_settings = training_lane_set.raw;
-+
-+ /* call VBIOS table to set voltage swing and pre-emphasis */
-+
-+ dal_bios_parser_transmitter_control(
-+ dal_adapter_service_get_bios_parser(
-+ enc->adapter_service), &cntl);
-+ }
-+
-+ return ENCODER_RESULT_OK;
-+}
-+
-+/* return value is bit-vector */
-+static uint8_t get_frontend_source(
-+ enum engine_id engine)
-+{
-+ switch (engine) {
-+ case ENGINE_ID_DIGA:
-+ return DCE110_DIG_FE_SOURCE_SELECT_DIGA;
-+ case ENGINE_ID_DIGB:
-+ return DCE110_DIG_FE_SOURCE_SELECT_DIGB;
-+ case ENGINE_ID_DIGC:
-+ return DCE110_DIG_FE_SOURCE_SELECT_DIGC;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ return DCE110_DIG_FE_SOURCE_SELECT_INVALID;
-+ }
-+}
-+
-+static void configure_encoder(
-+ struct link_encoder *enc,
-+ enum engine_id engine,
-+ const struct link_settings *link_settings)
-+{
-+ uint32_t addr;
-+ uint32_t value;
-+
-+ /* set number of lanes */
-+ addr = mmDP_CONFIG + enc->be_engine_offset;
-+ value = dal_read_reg(enc->ctx, addr);
-+ set_reg_field_value(value, link_settings->lane_count - LANE_COUNT_ONE,
-+ DP_CONFIG, DP_UDI_LANES);
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+}
-+
-+static bool is_panel_powered_on(struct link_encoder *link_enc)
-+{
-+ uint32_t value;
-+ bool ret;
-+
-+ value = dal_read_reg(link_enc->ctx,
-+ mmLVTMA_PWRSEQ_STATE);
-+
-+ ret = get_reg_field_value(value,
-+ LVTMA_PWRSEQ_STATE, LVTMA_PWRSEQ_TARGET_STATE_R);
-+
-+ return ret == 1;
-+}
-+
-+/*
-+ * @brief
-+ * eDP only. Control the power of the eDP panel.
-+ */
-+static enum encoder_result link_encoder_edp_power_control(
-+ struct link_encoder *link_enc,
-+ bool power_up)
-+{
-+ struct bp_transmitter_control cntl = { 0 };
-+ enum bp_result bp_result;
-+
-+ if (dal_graphics_object_id_get_connector_id(link_enc->connector) !=
-+ CONNECTOR_ID_EDP) {
-+ BREAK_TO_DEBUGGER();
-+ return ENCODER_RESULT_ERROR;
-+ }
-+
-+ if ((power_up && !is_panel_powered_on(link_enc)) ||
-+ (!power_up && is_panel_powered_on(link_enc))) {
-+
-+ /* Send VBIOS command to prompt eDP panel power */
-+
-+ dal_logger_write(link_enc->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_RESUME_S3,
-+ "%s: Panel Power action: %s\n",
-+ __func__, (power_up ? "On":"Off"));
-+
-+ cntl.action = power_up ?
-+ TRANSMITTER_CONTROL_POWER_ON :
-+ TRANSMITTER_CONTROL_POWER_OFF;
-+ cntl.transmitter = link_enc->transmitter;
-+ cntl.connector_obj_id = link_enc->connector;
-+ cntl.coherent = false;
-+ cntl.lanes_number = LANE_COUNT_FOUR;
-+ cntl.hpd_sel = link_enc->hpd_source;
-+
-+ bp_result = dal_bios_parser_transmitter_control(
-+ dal_adapter_service_get_bios_parser(
-+ link_enc->adapter_service), &cntl);
-+
-+ if (BP_RESULT_OK != bp_result) {
-+
-+ dal_logger_write(link_enc->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_HW_TRACE_RESUME_S3,
-+ "%s: Panel Power bp_result: %d\n",
-+ __func__, bp_result);
-+ }
-+ } else {
-+ dal_logger_write(link_enc->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_RESUME_S3,
-+ "%s: Skipping Panel Power action: %s\n",
-+ __func__, (power_up ? "On":"Off"));
-+ }
-+
-+ return ENCODER_RESULT_OK;
-+}
-+
-+/*
-+ * @brief
-+ * eDP only.
-+ */
-+static void link_encoder_edp_wait_for_hpd_ready(
-+ struct link_encoder *link_enc,
-+ struct graphics_object_id connector,
-+ bool power_up)
-+{
-+ struct adapter_service *as = link_enc->adapter_service;
-+ struct irq *hpd;
-+ bool edp_hpd_high = false;
-+ uint32_t time_elapsed = 0;
-+ uint32_t timeout = power_up ?
-+ PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT;
-+
-+ if (dal_graphics_object_id_get_connector_id(connector) !=
-+ CONNECTOR_ID_EDP) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ if (!power_up && dal_adapter_service_is_feature_supported(
-+ FEATURE_NO_HPD_LOW_POLLING_VCC_OFF))
-+ /* from KV, we will not HPD low after turning off VCC -
-+ * instead, we will check the SW timer in power_up(). */
-+ return;
-+
-+ /* when we power on/off the eDP panel,
-+ * we need to wait until SENSE bit is high/low */
-+
-+ /* obtain HPD */
-+
-+ hpd = dal_adapter_service_obtain_hpd_irq(as, connector);
-+
-+ if (!hpd) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ dal_irq_open(hpd);
-+
-+ /* wait until timeout or panel detected */
-+
-+ do {
-+ uint32_t detected = 0;
-+
-+ dal_irq_get_value(hpd, &detected);
-+
-+ if (!(detected ^ power_up)) {
-+ edp_hpd_high = true;
-+ break;
-+ }
-+
-+ dc_service_sleep_in_milliseconds(link_enc->ctx, HPD_CHECK_INTERVAL);
-+
-+ time_elapsed += HPD_CHECK_INTERVAL;
-+ } while (time_elapsed < timeout);
-+
-+ dal_irq_close(hpd);
-+
-+ dal_adapter_service_release_irq(as, hpd);
-+
-+ if (false == edp_hpd_high) {
-+ dal_logger_write(link_enc->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_HW_TRACE_RESUME_S3,
-+ "%s: wait timed out!\n", __func__);
-+ }
-+}
-+
-+static void aux_initialize(
-+ struct link_encoder *link_enc,
-+ enum hpd_source_id hpd_source)
-+{
-+ uint32_t addr = mmAUX_CONTROL + link_enc->aux_channel_offset;
-+
-+ uint32_t value = dal_read_reg(link_enc->ctx, addr);
-+
-+ set_reg_field_value(value, hpd_source, AUX_CONTROL, AUX_HPD_SEL);
-+ set_reg_field_value(value, 0, AUX_CONTROL, AUX_LS_READ_EN);
-+ dal_write_reg(link_enc->ctx, addr, value);
-+
-+ addr = mmAUX_DPHY_RX_CONTROL0 + link_enc->aux_channel_offset;
-+ value = dal_read_reg(link_enc->ctx, addr);
-+
-+ /* 1/4 window (the maximum allowed) */
-+ set_reg_field_value(value, 1,
-+ AUX_DPHY_RX_CONTROL0, AUX_RX_RECEIVE_WINDOW);
-+ dal_write_reg(link_enc->ctx,
-+ mmAUX_DPHY_RX_CONTROL0 + link_enc->aux_channel_offset,
-+ value);
-+
-+}
-+
-+/*todo: cloned in stream enc, fix*/
-+static bool is_panel_backlight_on(struct link_encoder *link_enc)
-+{
-+ uint32_t value;
-+
-+ value = dal_read_reg(link_enc->ctx, mmLVTMA_PWRSEQ_CNTL);
-+
-+ return get_reg_field_value(value, LVTMA_PWRSEQ_CNTL, LVTMA_BLON);
-+}
-+
-+/*todo: cloned in stream enc, fix*/
-+/*
-+ * @brief
-+ * eDP only. Control the backlight of the eDP panel
-+ */
-+static enum encoder_result link_encoder_edp_backlight_control(
-+ struct link_encoder *link_enc,
-+ bool enable)
-+{
-+ struct bp_transmitter_control cntl = { 0 };
-+
-+ if (dal_graphics_object_id_get_connector_id(link_enc->connector)
-+ != CONNECTOR_ID_EDP) {
-+ BREAK_TO_DEBUGGER();
-+ return ENCODER_RESULT_ERROR;
-+ }
-+
-+ if (enable && is_panel_backlight_on(link_enc)) {
-+ dal_logger_write(link_enc->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_RESUME_S3,
-+ "%s: panel already powered up. Do nothing.\n",
-+ __func__);
-+ return ENCODER_RESULT_OK;
-+ }
-+
-+ if (!enable && !is_panel_powered_on(link_enc)) {
-+ dal_logger_write(link_enc->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_RESUME_S3,
-+ "%s: panel already powered down. Do nothing.\n",
-+ __func__);
-+ return ENCODER_RESULT_OK;
-+ }
-+
-+ /* Send VBIOS command to control eDP panel backlight */
-+
-+ dal_logger_write(link_enc->ctx->logger,
-+ LOG_MAJOR_HW_TRACE,
-+ LOG_MINOR_HW_TRACE_RESUME_S3,
-+ "%s: backlight action: %s\n",
-+ __func__, (enable ? "On":"Off"));
-+
-+ cntl.action = enable ?
-+ TRANSMITTER_CONTROL_BACKLIGHT_ON :
-+ TRANSMITTER_CONTROL_BACKLIGHT_OFF;
-+ /*cntl.engine_id = ctx->engine;*/
-+ cntl.transmitter = link_enc->transmitter;
-+ cntl.connector_obj_id = link_enc->connector;
-+ /*todo: unhardcode*/
-+ cntl.lanes_number = LANE_COUNT_FOUR;
-+ cntl.hpd_sel = link_enc->hpd_source;
-+
-+ /* For eDP, the following delays might need to be considered
-+ * after link training completed:
-+ * idle period - min. accounts for required BS-Idle pattern,
-+ * max. allows for source frame synchronization);
-+ * 50 msec max. delay from valid video data from source
-+ * to video on dislpay or backlight enable.
-+ *
-+ * Disable the delay for now.
-+ * Enable it in the future if necessary.
-+ */
-+ /* dc_service_sleep_in_milliseconds(50); */
-+
-+ dal_bios_parser_transmitter_control(
-+ dal_adapter_service_get_bios_parser(
-+ link_enc->adapter_service), &cntl);
-+
-+ return ENCODER_RESULT_OK;
-+}
-+
-+/*
-+ * @brief
-+ * Configure digital transmitter and enable both encoder and transmitter
-+ * Actual output will be available after calling unblank()
-+ */
-+enum encoder_result dce110_link_encoder_enable_output(
-+ struct link_encoder *enc,
-+ const struct link_settings *link_settings,
-+ enum engine_id engine,
-+ enum clock_source_id clock_source,
-+ enum signal_type signal,
-+ enum dc_color_depth color_depth,
-+ uint32_t pixel_clock)
-+{
-+ struct bp_transmitter_control cntl = { 0 };
-+
-+ if (enc->connector.id == CONNECTOR_ID_EDP) {
-+ /* power up eDP panel */
-+
-+ link_encoder_edp_power_control(
-+ enc, true);
-+
-+ link_encoder_edp_wait_for_hpd_ready(
-+ enc, enc->connector, true);
-+
-+ /* have to turn off the backlight
-+ * before power down eDP panel */
-+ link_encoder_edp_backlight_control(
-+ enc, true);
-+ }
-+
-+ /* Enable the PHY */
-+
-+ /* number_of_lanes is used for pixel clock adjust,
-+ * but it's not passed to asic_control.
-+ * We need to set number of lanes manually. */
-+ if (dc_is_dp_signal(signal))
-+ configure_encoder(enc, engine, link_settings);
-+
-+ cntl.action = TRANSMITTER_CONTROL_ENABLE;
-+ cntl.engine_id = engine;
-+ cntl.transmitter = enc->transmitter;
-+ cntl.pll_id = clock_source;
-+ cntl.signal = signal;
-+ cntl.lanes_number = link_settings->lane_count;
-+ cntl.hpd_sel = enc->hpd_source;
-+ if (dc_is_dp_signal(signal))
-+ cntl.pixel_clock = link_settings->link_rate
-+ * LINK_RATE_REF_FREQ_IN_KHZ;
-+ else
-+ cntl.pixel_clock = pixel_clock;
-+ cntl.color_depth = color_depth;
-+
-+ if (DELAY_AFTER_PIXEL_FORMAT_CHANGE)
-+ dc_service_sleep_in_milliseconds(
-+ enc->ctx,
-+ DELAY_AFTER_PIXEL_FORMAT_CHANGE);
-+
-+ dal_bios_parser_transmitter_control(
-+ dal_adapter_service_get_bios_parser(
-+ enc->adapter_service),
-+ &cntl);
-+
-+ return ENCODER_RESULT_OK;
-+}
-+
-+static bool is_dig_enabled(const struct link_encoder *link_enc)
-+{
-+ uint32_t value;
-+
-+ value = dal_read_reg(link_enc->ctx,
-+ mmDIG_BE_EN_CNTL + link_enc->be_engine_offset);
-+
-+ return get_reg_field_value(value, DIG_BE_EN_CNTL, DIG_ENABLE);
-+}
-+
-+static void link_encoder_disable(struct link_encoder *link_enc)
-+{
-+ uint32_t addr;
-+ uint32_t value;
-+
-+ /* reset training pattern */
-+ addr = mmDP_DPHY_TRAINING_PATTERN_SEL + link_enc->be_engine_offset;
-+ value = dal_read_reg(link_enc->ctx, addr);
-+ set_reg_field_value(value, 0,
-+ DP_DPHY_TRAINING_PATTERN_SEL,
-+ DPHY_TRAINING_PATTERN_SEL);
-+ dal_write_reg(link_enc->ctx, addr, value);
-+
-+ /* reset training complete */
-+ addr = mmDP_LINK_CNTL + link_enc->be_engine_offset;
-+ value = dal_read_reg(link_enc->ctx, addr);
-+ set_reg_field_value(value, 0, DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE);
-+ dal_write_reg(link_enc->ctx, addr, value);
-+
-+ /* reset panel mode */
-+ addr = mmDP_DPHY_INTERNAL_CTRL + link_enc->be_engine_offset;
-+ value = 0;
-+ dal_write_reg(link_enc->ctx, addr, value);
-+}
-+
-+/*
-+ * @brief
-+ * Disable transmitter and its encoder
-+ */
-+enum encoder_result dce110_link_encoder_disable_output(
-+ struct link_encoder *link_enc,
-+ enum signal_type signal)
-+{
-+ struct bp_transmitter_control cntl = { 0 };
-+
-+ if (link_enc->connector.id == CONNECTOR_ID_EDP) {
-+ /* have to turn off the backlight
-+ * before power down eDP panel */
-+ link_encoder_edp_backlight_control(
-+ link_enc, false);
-+ }
-+
-+ if (!is_dig_enabled(link_enc) &&
-+ dal_adapter_service_should_optimize(link_enc->adapter_service,
-+ OF_SKIP_POWER_DOWN_INACTIVE_ENCODER)) {
-+ return ENCODER_RESULT_OK;
-+ }
-+ /* Power-down RX and disable GPU PHY should be paired.
-+ * Disabling PHY without powering down RX may cause
-+ * symbol lock loss, on which we will get DP Sink interrupt. */
-+
-+ /* There is a case for the DP active dongles
-+ * where we want to disable the PHY but keep RX powered,
-+ * for those we need to ignore DP Sink interrupt
-+ * by checking lane count that has been set
-+ * on the last do_enable_output(). */
-+
-+ /* disable transmitter */
-+ cntl.action = TRANSMITTER_CONTROL_DISABLE;
-+ cntl.transmitter = link_enc->transmitter;
-+ cntl.hpd_sel = link_enc->hpd_source;
-+ cntl.signal = signal;
-+ cntl.connector_obj_id = link_enc->connector;
-+
-+ dal_bios_parser_transmitter_control(
-+ dal_adapter_service_get_bios_parser(
-+ link_enc->adapter_service), &cntl);
-+
-+ /* disable encoder */
-+ if (dc_is_dp_signal(signal))
-+ link_encoder_disable(link_enc);
-+
-+ if (link_enc->connector.id == CONNECTOR_ID_EDP) {
-+ /* power down eDP panel */
-+ /* TODO: Power control cause regression, we should implement
-+ * it properly, for now just comment it.
-+ *
-+ * link_encoder_edp_wait_for_hpd_ready(
-+ link_enc,
-+ link_enc->connector,
-+ false);
-+
-+ * link_encoder_edp_power_control(
-+ link_enc, false); */
-+ }
-+
-+ return ENCODER_RESULT_OK;
-+}
-+
-+static void hpd_initialize(
-+ struct link_encoder *enc,
-+ enum hpd_source_id hpd_source)
-+{
-+ /* Associate HPD with DIG_BE */
-+ const uint32_t addr = mmDIG_BE_CNTL + enc->be_engine_offset;
-+ uint32_t value = dal_read_reg(enc->ctx, addr);
-+
-+ set_reg_field_value(value, hpd_source, DIG_BE_CNTL, DIG_HPD_SELECT);
-+ dal_write_reg(enc->ctx, addr, value);
-+}
-+
-+enum encoder_result dce110_link_encoder_power_up(
-+ struct link_encoder *enc)
-+{
-+ struct bp_transmitter_control cntl = { 0 };
-+
-+ enum bp_result result;
-+
-+ cntl.action = TRANSMITTER_CONTROL_INIT;
-+ cntl.engine_id = ENGINE_ID_UNKNOWN;
-+ cntl.transmitter = enc->transmitter;
-+ cntl.connector_obj_id = enc->connector;
-+ cntl.lanes_number = LANE_COUNT_FOUR;
-+ cntl.coherent = false;
-+ cntl.hpd_sel = enc->hpd_source;
-+
-+ result = dal_bios_parser_transmitter_control(
-+ dal_adapter_service_get_bios_parser(
-+ enc->adapter_service),
-+ &cntl);
-+
-+ if (result != BP_RESULT_OK) {
-+ dal_logger_write(enc->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_ENCODER,
-+ "%s: Failed to execute VBIOS command table!\n",
-+ __func__);
-+ BREAK_TO_DEBUGGER();
-+ return ENCODER_RESULT_ERROR;
-+ }
-+
-+ if (enc->connector.id == CONNECTOR_ID_LVDS) {
-+ cntl.action = TRANSMITTER_CONTROL_BACKLIGHT_BRIGHTNESS;
-+
-+ result = dal_bios_parser_transmitter_control(
-+ dal_adapter_service_get_bios_parser(
-+ enc->adapter_service),
-+ &cntl);
-+ ASSERT(result == BP_RESULT_OK);
-+
-+ } else if (enc->connector.id == CONNECTOR_ID_EDP) {
-+ link_encoder_edp_power_control(enc, true);
-+
-+ link_encoder_edp_wait_for_hpd_ready(
-+ enc, enc->connector, true);
-+
-+ }
-+ aux_initialize(enc, enc->hpd_source);
-+
-+ /* reinitialize HPD.
-+ * hpd_initialize() will pass DIG_FE id to HW context.
-+ * All other routine within HW context will use fe_engine_offset
-+ * as DIG_FE id even caller pass DIG_FE id.
-+ * So this routine must be called first. */
-+ hpd_initialize(enc, enc->hpd_source);
-+
-+ return ENCODER_RESULT_OK;
-+}
-+
-+
-+static bool validate_dvi_output(
-+ const struct link_encoder *enc,
-+ enum signal_type connector_signal,
-+ enum signal_type signal,
-+ const struct dc_crtc_timing *crtc_timing)
-+{
-+ uint32_t max_pixel_clock = TMDS_MAX_PIXEL_CLOCK;
-+
-+ if (enc->features.max_pixel_clock < TMDS_MAX_PIXEL_CLOCK)
-+ max_pixel_clock = enc->features.max_pixel_clock;
-+
-+ if (signal == SIGNAL_TYPE_DVI_DUAL_LINK)
-+ max_pixel_clock <<= 1;
-+
-+ /* This handles the case of HDMI downgrade to DVI we don't want to
-+ * we don't want to cap the pixel clock if the DDI is not DVI.
-+ */
-+ if (connector_signal != SIGNAL_TYPE_DVI_DUAL_LINK &&
-+ connector_signal != SIGNAL_TYPE_DVI_SINGLE_LINK)
-+ max_pixel_clock = enc->features.max_pixel_clock;
-+
-+ /* DVI only support RGB pixel encoding */
-+ if (crtc_timing->pixel_encoding != PIXEL_ENCODING_RGB)
-+ return false;
-+
-+ if (crtc_timing->pix_clk_khz < TMDS_MIN_PIXEL_CLOCK)
-+ return false;
-+
-+ if (crtc_timing->pix_clk_khz > max_pixel_clock)
-+ return false;
-+
-+ /* DVI supports 6/8bpp single-link and 10/16bpp dual-link */
-+ switch (crtc_timing->display_color_depth) {
-+ case COLOR_DEPTH_666:
-+ case COLOR_DEPTH_888:
-+ break;
-+ case COLOR_DEPTH_101010:
-+ case COLOR_DEPTH_161616:
-+ if (signal != SIGNAL_TYPE_DVI_DUAL_LINK)
-+ return false;
-+ break;
-+ default:
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+static bool validate_hdmi_output(
-+ const struct link_encoder *enc,
-+ const struct dc_crtc_timing *crtc_timing,
-+ uint32_t max_tmds_clk_from_edid_in_mhz,
-+ enum dc_color_depth max_hdmi_deep_color,
-+ uint32_t max_hdmi_pixel_clock)
-+{
-+ enum dc_color_depth max_deep_color = max_hdmi_deep_color;
-+
-+ /* expressed in KHz */
-+ uint32_t pixel_clock = 0;
-+
-+ if (max_deep_color > enc->features.max_deep_color)
-+ max_deep_color = enc->features.max_deep_color;
-+
-+ if (max_deep_color < crtc_timing->display_color_depth)
-+ return false;
-+
-+ if (crtc_timing->pix_clk_khz < TMDS_MIN_PIXEL_CLOCK)
-+ return false;
-+
-+ switch (crtc_timing->display_color_depth) {
-+ case COLOR_DEPTH_666:
-+ pixel_clock = (crtc_timing->pix_clk_khz * 3) >> 2;
-+ break;
-+ case COLOR_DEPTH_888:
-+ pixel_clock = crtc_timing->pix_clk_khz;
-+ break;
-+ case COLOR_DEPTH_101010:
-+ pixel_clock = (crtc_timing->pix_clk_khz * 10) >> 3;
-+ break;
-+ case COLOR_DEPTH_121212:
-+ pixel_clock = (crtc_timing->pix_clk_khz * 3) >> 1;
-+ break;
-+ case COLOR_DEPTH_161616:
-+ pixel_clock = crtc_timing->pix_clk_khz << 1;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (max_tmds_clk_from_edid_in_mhz > 0)
-+ if (pixel_clock > max_tmds_clk_from_edid_in_mhz * 1000)
-+ return false;
-+
-+ if ((pixel_clock == 0) ||
-+ (pixel_clock > max_hdmi_pixel_clock) ||
-+ (pixel_clock > enc->features.max_pixel_clock))
-+ return false;
-+
-+ /*
-+ * Restriction: allow non-CE mode (IT mode) to support RGB only.
-+ * When it is IT mode, the format mode will be 0,
-+ * but currently the code is broken,
-+ * VIDEO FORMAT is always 0 in validatepathMode().
-+ * Due to overscan change - need fix there and test the impact - to do.
-+ */
-+ if (crtc_timing->timing_standard != TIMING_STANDARD_CEA861 &&
-+ crtc_timing->timing_standard != TIMING_STANDARD_HDMI)
-+ if (crtc_timing->pixel_encoding !=
-+ PIXEL_ENCODING_RGB)
-+ return false;
-+
-+ return true;
-+}
-+
-+static bool validate_rgb_output(
-+ const struct link_encoder *enc,
-+ const struct dc_crtc_timing *crtc_timing)
-+{
-+ if (crtc_timing->pix_clk_khz > enc->features.max_pixel_clock)
-+ return false;
-+
-+ if (crtc_timing->pixel_encoding != PIXEL_ENCODING_RGB)
-+ return false;
-+
-+ return true;
-+}
-+
-+static bool validate_dp_output(
-+ const struct link_encoder *enc,
-+ const struct dc_crtc_timing *crtc_timing)
-+{
-+ if (crtc_timing->pix_clk_khz > enc->features.max_pixel_clock)
-+ return false;
-+
-+ /* default RGB only */
-+ if (crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB)
-+ return true;
-+
-+ if (enc->features.flags.bits.IS_YCBCR_CAPABLE)
-+ return true;
-+
-+ /* for DCE 8.x or later DP Y-only feature,
-+ * we need ASIC cap + FeatureSupportDPYonly, not support 666 */
-+ if (crtc_timing->flags.Y_ONLY &&
-+ enc->features.flags.bits.IS_YCBCR_CAPABLE &&
-+ crtc_timing->display_color_depth != COLOR_DEPTH_666)
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool validate_wireless_output(
-+ const struct link_encoder *enc,
-+ const struct dc_crtc_timing *crtc_timing)
-+{
-+ if (crtc_timing->pix_clk_khz > enc->features.max_pixel_clock)
-+ return false;
-+
-+ /* Wireless only supports YCbCr444 */
-+ if (crtc_timing->pixel_encoding ==
-+ PIXEL_ENCODING_YCBCR444)
-+ return true;
-+
-+ return false;
-+}
-+
-+enum encoder_result dce110_link_encoder_validate_output_with_stream(
-+ struct link_encoder *enc,
-+ const struct core_stream *stream)
-+{
-+ bool is_valid;
-+
-+ switch (stream->signal) {
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
-+ case SIGNAL_TYPE_DVI_DUAL_LINK:
-+ is_valid = validate_dvi_output(
-+ enc,
-+ stream->sink->link->public.connector_signal,
-+ stream->signal,
-+ &stream->public.timing);
-+ break;
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ is_valid = validate_hdmi_output(
-+ enc,
-+ &stream->public.timing,
-+ stream->max_tmds_clk_from_edid_in_mhz,
-+ stream->max_hdmi_deep_color,
-+ stream->max_hdmi_pixel_clock);
-+ break;
-+ case SIGNAL_TYPE_RGB:
-+ is_valid = validate_rgb_output(
-+ enc, &stream->public.timing);
-+ break;
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP:
-+ is_valid = validate_dp_output(
-+ enc, &stream->public.timing);
-+ break;
-+ case SIGNAL_TYPE_WIRELESS:
-+ is_valid = validate_wireless_output(
-+ enc, &stream->public.timing);
-+ break;
-+ default:
-+ is_valid = true;
-+ break;
-+ }
-+
-+ return is_valid ? ENCODER_RESULT_OK : ENCODER_RESULT_ERROR;
-+}
-+
-+/*
-+ * get_supported_stream_engines
-+ *
-+ * @brief
-+ * get a list of supported engine
-+ *
-+ * @param
-+ * const struct encoder_impl *enc - not used.
-+ *
-+ * @return
-+ * list of engines with supported ones enabled.
-+ */
-+union supported_stream_engines dce110_get_supported_stream_engines(
-+ const struct link_encoder *enc)
-+{
-+ union supported_stream_engines result = {.u_all = 0};
-+
-+ result.engine.ENGINE_ID_DIGA = 1;
-+ result.engine.ENGINE_ID_DIGB = 1;
-+ result.engine.ENGINE_ID_DIGC = 1;
-+
-+ if (enc->connector.id == CONNECTOR_ID_EDP /*|| wireless*/)
-+ result.u_all = (1 << enc->preferred_engine);
-+
-+ return result;
-+}
-+
-+void dce110_link_encoder_set_lcd_backlight_level(
-+ struct link_encoder *enc,
-+ uint32_t level)
-+{
-+ struct dc_context *ctx = enc->ctx;
-+
-+ const uint32_t backlight_update_pending_max_retry = 1000;
-+
-+ uint32_t backlight;
-+ uint32_t backlight_period;
-+ uint32_t backlight_lock;
-+
-+ uint32_t i;
-+ uint32_t backlight_24bit;
-+ uint32_t backlight_17bit;
-+ uint32_t backlight_16bit;
-+ uint32_t masked_pwm_period;
-+ uint8_t rounding_bit;
-+ uint8_t bit_count;
-+ uint64_t active_duty_cycle;
-+
-+ backlight = dal_read_reg(ctx, mmBL_PWM_CNTL);
-+ backlight_period = dal_read_reg(ctx, mmBL_PWM_PERIOD_CNTL);
-+ backlight_lock = dal_read_reg(ctx, mmBL_PWM_GRP1_REG_LOCK);
-+
-+ /*
-+ * 1. Convert 8-bit value to 17 bit U1.16 format
-+ * (1 integer, 16 fractional bits)
-+ */
-+
-+ /* 1.1 multiply 8 bit value by 0x10101 to get a 24 bit value,
-+ * effectively multiplying value by 256/255
-+ * eg. for a level of 0xEF, backlight_24bit = 0xEF * 0x10101 = 0xEFEFEF
-+ */
-+ backlight_24bit = level * 0x10101;
-+
-+ /* 1.2 The upper 16 bits of the 24 bit value is the fraction, lower 8
-+ * used for rounding, take most significant bit of fraction for
-+ * rounding, e.g. for 0xEFEFEF, rounding bit is 1
-+ */
-+ rounding_bit = (backlight_24bit >> 7) & 1;
-+
-+ /* 1.3 Add the upper 16 bits of the 24 bit value with the rounding bit
-+ * resulting in a 17 bit value e.g. 0xEFF0 = (0xEFEFEF >> 8) + 1
-+ */
-+ backlight_17bit = (backlight_24bit >> 8) + rounding_bit;
-+
-+ /*
-+ * 2. Find 16 bit backlight active duty cycle, where 0 <= backlight
-+ * active duty cycle <= backlight period
-+ */
-+
-+ /* 2.1 Apply bitmask for backlight period value based on value of BITCNT
-+ */
-+ {
-+ uint32_t pwm_period_bitcnt = get_reg_field_value(
-+ backlight_period,
-+ BL_PWM_PERIOD_CNTL,
-+ BL_PWM_PERIOD_BITCNT);
-+ if (pwm_period_bitcnt == 0)
-+ bit_count = 16;
-+ else
-+ bit_count = pwm_period_bitcnt;
-+ }
-+
-+ /* e.g. maskedPwmPeriod = 0x24 when bitCount is 6 */
-+ masked_pwm_period =
-+ get_reg_field_value(
-+ backlight_period,
-+ BL_PWM_PERIOD_CNTL,
-+ BL_PWM_PERIOD) & ((1 << bit_count) - 1);
-+
-+ /* 2.2 Calculate integer active duty cycle required upper 16 bits
-+ * contain integer component, lower 16 bits contain fractional component
-+ * of active duty cycle e.g. 0x21BDC0 = 0xEFF0 * 0x24
-+ */
-+ active_duty_cycle = backlight_17bit * masked_pwm_period;
-+
-+ /* 2.3 Calculate 16 bit active duty cycle from integer and fractional
-+ * components shift by bitCount then mask 16 bits and add rounding bit
-+ * from MSB of fraction e.g. 0x86F7 = ((0x21BDC0 >> 6) & 0xFFF) + 0
-+ */
-+ backlight_16bit = active_duty_cycle >> bit_count;
-+ backlight_16bit &= 0xFFFF;
-+ backlight_16bit += (active_duty_cycle >> (bit_count - 1)) & 0x1;
-+ set_reg_field_value(
-+ backlight,
-+ backlight_16bit,
-+ BL_PWM_CNTL,
-+ BL_ACTIVE_INT_FRAC_CNT);
-+
-+ /*
-+ * 3. Program register with updated value
-+ */
-+
-+ /* 3.1 Lock group 2 backlight registers */
-+ set_reg_field_value(
-+ backlight_lock,
-+ 1,
-+ BL_PWM_GRP1_REG_LOCK,
-+ BL_PWM_GRP1_IGNORE_MASTER_LOCK_EN);
-+ set_reg_field_value(
-+ backlight_lock,
-+ 1,
-+ BL_PWM_GRP1_REG_LOCK,
-+ BL_PWM_GRP1_REG_LOCK);
-+ dal_write_reg(ctx, mmBL_PWM_GRP1_REG_LOCK, backlight_lock);
-+
-+ /* 3.2 Write new active duty cycle */
-+ dal_write_reg(ctx, mmBL_PWM_CNTL, backlight);
-+
-+ /* 3.3 Unlock group 2 backlight registers */
-+ set_reg_field_value(
-+ backlight_lock,
-+ 0,
-+ BL_PWM_GRP1_REG_LOCK,
-+ BL_PWM_GRP1_REG_LOCK);
-+ dal_write_reg(ctx, mmBL_PWM_GRP1_REG_LOCK, backlight_lock);
-+
-+ /* 5.4.4 Wait for pending bit to be cleared */
-+ for (i = 0; i < backlight_update_pending_max_retry; ++i) {
-+ backlight_lock = dal_read_reg(ctx, mmBL_PWM_GRP1_REG_LOCK);
-+ if (!get_reg_field_value(
-+ backlight_lock,
-+ BL_PWM_GRP1_REG_LOCK,
-+ BL_PWM_GRP1_REG_UPDATE_PENDING))
-+ break;
-+
-+ dc_service_delay_in_microseconds(ctx, 10);
-+ }
-+}
-+
-+/*TODO: move to correct dce specific file*/
-+/**
-+* set_afmt_memory_power_state
-+*
-+* @brief
-+* Power up audio formatter memory that is mapped to specified DIG
-+*/
-+void dce110_set_afmt_memory_power_state(
-+ const struct dc_context *ctx,
-+ enum engine_id id,
-+ bool enable)
-+{
-+ uint32_t value;
-+ uint32_t mem_pwr_force;
-+
-+ value = dal_read_reg(ctx, mmDCO_MEM_PWR_CTRL);
-+
-+ if (enable)
-+ mem_pwr_force = 0;
-+ else
-+ mem_pwr_force = 3;
-+
-+ /* force shutdown mode for appropriate AFMT memory */
-+ switch (id) {
-+ case ENGINE_ID_DIGA:
-+ set_reg_field_value(
-+ value,
-+ mem_pwr_force,
-+ DCO_MEM_PWR_CTRL,
-+ HDMI0_MEM_PWR_FORCE);
-+ break;
-+ case ENGINE_ID_DIGB:
-+ set_reg_field_value(
-+ value,
-+ mem_pwr_force,
-+ DCO_MEM_PWR_CTRL,
-+ HDMI1_MEM_PWR_FORCE);
-+ break;
-+ case ENGINE_ID_DIGC:
-+ set_reg_field_value(
-+ value,
-+ mem_pwr_force,
-+ DCO_MEM_PWR_CTRL,
-+ HDMI2_MEM_PWR_FORCE);
-+ break;
-+ default:
-+ dal_logger_write(
-+ ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_ENCODER,
-+ "%s: Invalid Engine Id\n",
-+ __func__);
-+ break;
-+ }
-+
-+ dal_write_reg(ctx, mmDCO_MEM_PWR_CTRL, value);
-+}
-+
-+void dce110_link_encoder_update_mst_stream_allocation_table(
-+ struct link_encoder *enc,
-+ const struct dp_mst_stream_allocation_table *table,
-+ bool is_removal)
-+{
-+ int32_t addr_offset = enc->be_engine_offset;
-+ uint32_t value0;
-+ uint32_t value1;
-+ uint32_t retries = 0;
-+
-+ /* For CZ, there are only 3 pipes. So Virtual channel is up 3.*/
-+
-+ /* --- Set MSE Stream Attribute -
-+ * Setup VC Payload Table on Tx Side,
-+ * Issue allocation change trigger
-+ * to commit payload on both tx and rx side */
-+
-+ value0 = dal_read_reg(enc->ctx, mmDP_MSE_SAT0 + addr_offset);
-+ value1 = dal_read_reg(enc->ctx, mmDP_MSE_SAT1 + addr_offset);
-+
-+ if (table->stream_count >= 1) {
-+ set_reg_field_value(
-+ value0,
-+ table->stream_allocations[0].engine,
-+ DP_MSE_SAT0,
-+ DP_MSE_SAT_SRC0);
-+
-+ set_reg_field_value(
-+ value0,
-+ table->stream_allocations[0].slot_count,
-+ DP_MSE_SAT0,
-+ DP_MSE_SAT_SLOT_COUNT0);
-+ }
-+
-+ if (table->stream_count >= 2) {
-+ set_reg_field_value(
-+ value0,
-+ table->stream_allocations[1].engine,
-+ DP_MSE_SAT0,
-+ DP_MSE_SAT_SRC1);
-+
-+ set_reg_field_value(
-+ value0,
-+ table->stream_allocations[1].slot_count,
-+ DP_MSE_SAT0,
-+ DP_MSE_SAT_SLOT_COUNT1);
-+ }
-+
-+ if (table->stream_count >= 3) {
-+ set_reg_field_value(
-+ value1,
-+ table->stream_allocations[2].engine,
-+ DP_MSE_SAT1,
-+ DP_MSE_SAT_SRC2);
-+
-+ set_reg_field_value(
-+ value1,
-+ table->stream_allocations[2].slot_count,
-+ DP_MSE_SAT1,
-+ DP_MSE_SAT_SLOT_COUNT2);
-+ }
-+
-+ /* update ASIC MSE stream allocation table */
-+ dal_write_reg(enc->ctx, mmDP_MSE_SAT0 + addr_offset, value0);
-+ dal_write_reg(enc->ctx, mmDP_MSE_SAT1 + addr_offset, value1);
-+
-+ /* --- wait for transaction finish */
-+
-+ /* send allocation change trigger (ACT) ?
-+ * this step first sends the ACT,
-+ * then double buffers the SAT into the hardware
-+ * making the new allocation active on the DP MST mode link */
-+
-+ value0 = dal_read_reg(enc->ctx, mmDP_MSE_SAT_UPDATE + addr_offset);
-+
-+ /* DP_MSE_SAT_UPDATE:
-+ * 0 - No Action
-+ * 1 - Update SAT with trigger
-+ * 2 - Update SAT without trigger */
-+
-+ set_reg_field_value(
-+ value0,
-+ 1,
-+ DP_MSE_SAT_UPDATE,
-+ DP_MSE_SAT_UPDATE);
-+
-+ dal_write_reg(enc->ctx, mmDP_MSE_SAT_UPDATE + addr_offset, value0);
-+
-+ /* wait for update to complete
-+ * (i.e. DP_MSE_SAT_UPDATE field is reset to 0)
-+ * then wait for the transmission
-+ * of at least 16 MTP headers on immediate local link.
-+ * i.e. DP_MSE_16_MTP_KEEPOUT field (read only) is reset to 0
-+ * a value of 1 indicates that DP MST mode
-+ * is in the 16 MTP keepout region after a VC has been added.
-+ * MST stream bandwidth (VC rate) can be configured
-+ * after this bit is cleared */
-+
-+ do {
-+ dc_service_delay_in_microseconds(enc->ctx, 10);
-+
-+ value0 = dal_read_reg(enc->ctx,
-+ mmDP_MSE_SAT_UPDATE + addr_offset);
-+
-+ value1 = get_reg_field_value(
-+ value0,
-+ DP_MSE_SAT_UPDATE,
-+ DP_MSE_16_MTP_KEEPOUT);
-+
-+ /* bit field DP_MSE_SAT_UPDATE is set to 1 already */
-+ if (value1)
-+ break;
-+ ++retries;
-+ } while (retries < DP_MST_UPDATE_MAX_RETRY);
-+
-+ /* TODO should not need. clean this after light up
-+ * if (is_removal)
-+ * dal_write_reg(enc->ctx, addr, value);
-+ */
-+}
-+
-+void dce110_link_encoder_set_mst_bandwidth(
-+ struct link_encoder *enc,
-+ enum engine_id engine,
-+ struct fixed31_32 avg_time_slots_per_mtp)
-+{
-+ uint32_t x = dal_fixed31_32_floor(
-+ avg_time_slots_per_mtp);
-+
-+ uint32_t y = dal_fixed31_32_ceil(
-+ dal_fixed31_32_shl(
-+ dal_fixed31_32_sub_int(
-+ avg_time_slots_per_mtp,
-+ x),
-+ 26));
-+
-+ {
-+ const uint32_t addr = mmDP_MSE_RATE_CNTL +
-+ fe_engine_offsets[engine];
-+ uint32_t value = dal_read_reg(enc->ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ x,
-+ DP_MSE_RATE_CNTL,
-+ DP_MSE_RATE_X);
-+
-+ set_reg_field_value(
-+ value,
-+ y,
-+ DP_MSE_RATE_CNTL,
-+ DP_MSE_RATE_Y);
-+
-+ dal_write_reg(enc->ctx, addr, value);
-+ }
-+
-+ /* wait for update to be completed on the link
-+ * i.e. DP_MSE_RATE_UPDATE_PENDING field (read only)
-+ * is reset to 0 (not pending) */
-+ {
-+ const uint32_t addr = mmDP_MSE_RATE_UPDATE +
-+ fe_engine_offsets[engine];
-+ uint32_t value, field;
-+ uint32_t retries = 0;
-+
-+ do {
-+ value = dal_read_reg(enc->ctx, addr);
-+
-+ field = get_reg_field_value(
-+ value,
-+ DP_MSE_RATE_UPDATE,
-+ DP_MSE_RATE_UPDATE_PENDING);
-+
-+ if (!(field &
-+ DP_MSE_RATE_UPDATE__DP_MSE_RATE_UPDATE_PENDING_MASK))
-+ break;
-+
-+ dc_service_delay_in_microseconds(enc->ctx, 10);
-+
-+ ++retries;
-+ } while (retries < DP_MST_UPDATE_MAX_RETRY);
-+ }
-+}
-+
-+void dce110_link_encoder_connect_dig_be_to_fe(
-+ struct link_encoder *enc,
-+ enum engine_id engine,
-+ bool connect)
-+{
-+ uint32_t addr;
-+ uint32_t value;
-+ uint32_t field;
-+
-+ if (engine != ENGINE_ID_UNKNOWN) {
-+ addr = mmDIG_BE_CNTL + enc->be_engine_offset;
-+ value = dal_read_reg(enc->ctx, addr);
-+
-+ field = get_reg_field_value(
-+ value,
-+ DIG_BE_CNTL,
-+ DIG_FE_SOURCE_SELECT);
-+
-+ if (connect)
-+ field |= get_frontend_source(engine);
-+ else
-+ field &= ~get_frontend_source(engine);
-+
-+ set_reg_field_value(
-+ value,
-+ field,
-+ DIG_BE_CNTL,
-+ DIG_FE_SOURCE_SELECT);
-+ dal_write_reg(enc->ctx, addr, value);
-+ }
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.h
-new file mode 100644
-index 0000000..4331bf0
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_link_encoder.h
-@@ -0,0 +1,91 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_LINK_ENCODER__DCE110_H__
-+#define __DC_LINK_ENCODER__DCE110_H__
-+
-+struct link_encoder *dce110_link_encoder_create(
-+ const struct encoder_init_data *init);
-+void dce110_link_encoder_destroy(struct link_encoder **enc);
-+
-+void dce110_link_encoder_set_dp_phy_pattern(
-+ struct link_encoder *enc,
-+ const struct encoder_set_dp_phy_pattern_param *param);
-+
-+enum encoder_result dce110_link_encoder_power_up(struct link_encoder *enc);
-+
-+enum encoder_result dce110_link_encoder_dp_set_lane_settings(
-+ struct link_encoder *enc,
-+ const struct link_training_settings *link_settings);
-+
-+union supported_stream_engines dce110_get_supported_stream_engines(
-+ const struct link_encoder *enc);
-+
-+enum encoder_result dce110_link_encoder_validate_output_with_stream(
-+ struct link_encoder *enc,
-+ const struct core_stream *stream);
-+
-+void dce110_link_encoder_set_lcd_backlight_level(
-+ struct link_encoder *enc,
-+ uint32_t level);
-+
-+void dce110_link_encoder_setup(
-+ struct link_encoder *enc,
-+ enum signal_type signal);
-+
-+enum encoder_result dce110_link_encoder_enable_output(
-+ struct link_encoder *enc,
-+ const struct link_settings *link_settings,
-+ enum engine_id engine,
-+ enum clock_source_id clock_source,
-+ enum signal_type signal,
-+ enum dc_color_depth color_depth,
-+ uint32_t pixel_clock);
-+
-+enum encoder_result dce110_link_encoder_disable_output(
-+ struct link_encoder *link_enc,
-+ enum signal_type signal);
-+
-+void dce110_set_afmt_memory_power_state(
-+ const struct dc_context *ctx,
-+ enum engine_id id,
-+ bool enable);
-+
-+void dce110_link_encoder_update_mst_stream_allocation_table(
-+ struct link_encoder *enc,
-+ const struct dp_mst_stream_allocation_table *table,
-+ bool is_removal);
-+
-+void dce110_link_encoder_set_mst_bandwidth(
-+ struct link_encoder *enc,
-+ enum engine_id engine,
-+ struct fixed31_32 avg_time_slots_per_mtp);
-+
-+void dce110_link_encoder_connect_dig_be_to_fe(
-+ struct link_encoder *enc,
-+ enum engine_id engine,
-+ bool connect);
-+
-+#endif /* __DC_LINK_ENCODER__DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c
-new file mode 100644
-index 0000000..7391a0a
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.c
-@@ -0,0 +1,969 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#include "dal_services.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+/* TODO: this needs to be looked at, used by Stella's workaround*/
-+#include "gmc/gmc_8_2_d.h"
-+#include "gmc/gmc_8_2_sh_mask.h"
-+
-+#include "include/logger_interface.h"
-+#include "adapter_service_interface.h"
-+#include "inc/bandwidth_calcs.h"
-+
-+#include "dce110_mem_input.h"
-+
-+#define MAX_WATERMARK 0xFFFF
-+#define SAFE_NBP_MARK 0x7FFF
-+
-+#define DCP_REG(reg) (reg + mem_input110->offsets.dcp)
-+#define DMIF_REG(reg) (reg + mem_input110->offsets.dmif)
-+#define PIPE_REG(reg) (reg + mem_input110->offsets.pipe)
-+
-+static const struct dce110_mem_input_reg_offsets reg_offsets[] = {
-+{
-+ .dcp = 0,
-+ .dmif = 0,
-+ .pipe = 0,
-+},
-+{
-+ .dcp = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif = (mmDMIF_PG1_DPG_WATERMARK_MASK_CONTROL
-+ - mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE1_DMIF_BUFFER_CONTROL - mmPIPE0_DMIF_BUFFER_CONTROL),
-+},
-+{
-+ .dcp = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif = (mmDMIF_PG2_DPG_WATERMARK_MASK_CONTROL
-+ - mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE2_DMIF_BUFFER_CONTROL - mmPIPE0_DMIF_BUFFER_CONTROL),
-+}
-+};
-+
-+static void set_flip_control(
-+ struct dce110_mem_input *mem_input110,
-+ bool immediate)
-+{
-+ uint32_t value = 0;
-+
-+ value = dal_read_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_FLIP_CONTROL));
-+ set_reg_field_value(value, 0,
-+ GRPH_FLIP_CONTROL,
-+ GRPH_SURFACE_UPDATE_IMMEDIATE_EN);
-+ set_reg_field_value(value, 0,
-+ GRPH_FLIP_CONTROL,
-+ GRPH_SURFACE_UPDATE_H_RETRACE_EN);
-+ if (immediate == true)
-+ set_reg_field_value(value, 1,
-+ GRPH_FLIP_CONTROL,
-+ GRPH_SURFACE_UPDATE_IMMEDIATE_EN);
-+
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_FLIP_CONTROL),
-+ value);
-+}
-+
-+static void program_sec_addr(
-+ struct dce110_mem_input *mem_input110,
-+ PHYSICAL_ADDRESS_LOC address)
-+{
-+ uint32_t value = 0;
-+ uint32_t temp = 0;
-+ /*high register MUST be programmed first*/
-+ temp = address.high_part &
-+GRPH_SECONDARY_SURFACE_ADDRESS_HIGH__GRPH_SECONDARY_SURFACE_ADDRESS_HIGH_MASK;
-+
-+ set_reg_field_value(value, temp,
-+ GRPH_SECONDARY_SURFACE_ADDRESS_HIGH,
-+ GRPH_SECONDARY_SURFACE_ADDRESS_HIGH);
-+
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_SECONDARY_SURFACE_ADDRESS_HIGH),
-+ value);
-+
-+ temp = 0;
-+ value = 0;
-+ temp = address.low_part >>
-+ GRPH_SECONDARY_SURFACE_ADDRESS__GRPH_SECONDARY_SURFACE_ADDRESS__SHIFT;
-+
-+ set_reg_field_value(value, temp,
-+ GRPH_SECONDARY_SURFACE_ADDRESS,
-+ GRPH_SECONDARY_SURFACE_ADDRESS);
-+
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_SECONDARY_SURFACE_ADDRESS),
-+ value);
-+}
-+
-+static void program_pri_addr(
-+ struct dce110_mem_input *mem_input110,
-+ PHYSICAL_ADDRESS_LOC address)
-+{
-+ uint32_t value = 0;
-+ uint32_t temp = 0;
-+
-+ /*high register MUST be programmed first*/
-+ temp = address.high_part &
-+GRPH_PRIMARY_SURFACE_ADDRESS_HIGH__GRPH_PRIMARY_SURFACE_ADDRESS_HIGH_MASK;
-+
-+ set_reg_field_value(value, temp,
-+ GRPH_PRIMARY_SURFACE_ADDRESS_HIGH,
-+ GRPH_PRIMARY_SURFACE_ADDRESS_HIGH);
-+
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_PRIMARY_SURFACE_ADDRESS_HIGH),
-+ value);
-+
-+ temp = 0;
-+ value = 0;
-+ temp = address.low_part >>
-+ GRPH_PRIMARY_SURFACE_ADDRESS__GRPH_PRIMARY_SURFACE_ADDRESS__SHIFT;
-+
-+ set_reg_field_value(value, temp,
-+ GRPH_PRIMARY_SURFACE_ADDRESS,
-+ GRPH_PRIMARY_SURFACE_ADDRESS);
-+
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_PRIMARY_SURFACE_ADDRESS),
-+ value);
-+}
-+
-+static void program_addr(
-+ struct dce110_mem_input *mem_input110,
-+ const struct dc_plane_address *addr)
-+{
-+ switch (addr->type) {
-+ case PLN_ADDR_TYPE_GRAPHICS:
-+ program_pri_addr(
-+ mem_input110,
-+ addr->grph.addr);
-+ break;
-+ case PLN_ADDR_TYPE_GRPH_STEREO:
-+ program_pri_addr(
-+ mem_input110,
-+ addr->grph_stereo.left_addr);
-+ program_sec_addr(
-+ mem_input110,
-+ addr->grph_stereo.right_addr);
-+ break;
-+ case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:
-+ case PLN_ADDR_TYPE_VIDEO_INTERLACED:
-+ case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE_STEREO:
-+ case PLN_ADDR_TYPE_VIDEO_INTERLACED_STEREO:
-+ default:
-+ /* not supported */
-+ BREAK_TO_DEBUGGER();
-+ }
-+}
-+
-+static void enable(struct dce110_mem_input *mem_input110)
-+{
-+ uint32_t value = 0;
-+
-+ value = dal_read_reg(mem_input110->base.ctx, DCP_REG(mmGRPH_ENABLE));
-+ set_reg_field_value(value, 1, GRPH_ENABLE, GRPH_ENABLE);
-+ dal_write_reg(mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_ENABLE),
-+ value);
-+}
-+
-+static void program_tiling(
-+ struct dce110_mem_input *mem_input110,
-+ const union plane_tiling_info *info,
-+ const enum surface_pixel_format pixel_format)
-+{
-+ uint32_t value = 0;
-+
-+ value = dal_read_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_CONTROL));
-+
-+ set_reg_field_value(value, info->grph.NUM_BANKS,
-+ GRPH_CONTROL, GRPH_NUM_BANKS);
-+
-+ set_reg_field_value(value, info->grph.BANK_WIDTH,
-+ GRPH_CONTROL, GRPH_BANK_WIDTH);
-+
-+ set_reg_field_value(value, info->grph.BANK_HEIGHT,
-+ GRPH_CONTROL, GRPH_BANK_HEIGHT);
-+
-+ set_reg_field_value(value, info->grph.TILE_ASPECT,
-+ GRPH_CONTROL, GRPH_MACRO_TILE_ASPECT);
-+
-+ set_reg_field_value(value, info->grph.TILE_SPLIT,
-+ GRPH_CONTROL, GRPH_TILE_SPLIT);
-+
-+ set_reg_field_value(value, info->grph.TILE_MODE,
-+ GRPH_CONTROL, GRPH_MICRO_TILE_MODE);
-+
-+ set_reg_field_value(value, info->grph.PIPE_CONFIG,
-+ GRPH_CONTROL, GRPH_PIPE_CONFIG);
-+
-+ set_reg_field_value(value, info->grph.ARRAY_MODE,
-+ GRPH_CONTROL, GRPH_ARRAY_MODE);
-+
-+ set_reg_field_value(value, 1,
-+ GRPH_CONTROL, GRPH_COLOR_EXPANSION_MODE);
-+
-+ set_reg_field_value(value, 0,
-+ GRPH_CONTROL, GRPH_Z);
-+
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_CONTROL),
-+ value);
-+}
-+
-+static void program_size_and_rotation(
-+ struct dce110_mem_input *mem_input110,
-+ enum dc_rotation_angle rotation,
-+ const union plane_size *plane_size)
-+{
-+ uint32_t value = 0;
-+ union plane_size local_size = *plane_size;
-+
-+ if (rotation == ROTATION_ANGLE_90 ||
-+ rotation == ROTATION_ANGLE_270) {
-+
-+ uint32_t swap;
-+
-+ swap = local_size.grph.surface_size.x;
-+ local_size.grph.surface_size.x =
-+ local_size.grph.surface_size.y;
-+ local_size.grph.surface_size.y = swap;
-+
-+ swap = local_size.grph.surface_size.width;
-+ local_size.grph.surface_size.width =
-+ local_size.grph.surface_size.height;
-+ local_size.grph.surface_size.height = swap;
-+ }
-+
-+ set_reg_field_value(value, local_size.grph.surface_size.x,
-+ GRPH_X_START, GRPH_X_START);
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_X_START),
-+ value);
-+
-+ value = 0;
-+ set_reg_field_value(value, local_size.grph.surface_size.y,
-+ GRPH_Y_START, GRPH_Y_START);
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_Y_START),
-+ value);
-+
-+ value = 0;
-+ set_reg_field_value(value, local_size.grph.surface_size.width,
-+ GRPH_X_END, GRPH_X_END);
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_X_END),
-+ value);
-+
-+ value = 0;
-+ set_reg_field_value(value, local_size.grph.surface_size.height,
-+ GRPH_Y_END, GRPH_Y_END);
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_Y_END),
-+ value);
-+
-+ value = 0;
-+ set_reg_field_value(value, local_size.grph.surface_pitch,
-+ GRPH_PITCH, GRPH_PITCH);
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_PITCH),
-+ value);
-+
-+
-+ value = 0;
-+ switch (rotation) {
-+ case ROTATION_ANGLE_90:
-+ set_reg_field_value(value, 3,
-+ HW_ROTATION, GRPH_ROTATION_ANGLE);
-+ break;
-+ case ROTATION_ANGLE_180:
-+ set_reg_field_value(value, 2,
-+ HW_ROTATION, GRPH_ROTATION_ANGLE);
-+ break;
-+ case ROTATION_ANGLE_270:
-+ set_reg_field_value(value, 1,
-+ HW_ROTATION, GRPH_ROTATION_ANGLE);
-+ break;
-+ default:
-+ set_reg_field_value(value, 0,
-+ HW_ROTATION, GRPH_ROTATION_ANGLE);
-+ break;
-+ }
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmHW_ROTATION),
-+ value);
-+}
-+
-+static void program_pixel_format(
-+ struct dce110_mem_input *mem_input110,
-+ enum surface_pixel_format format)
-+{
-+ if (format >= SURFACE_PIXEL_FORMAT_GRPH_BEGIN &&
-+ format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
-+ uint32_t value = 0;
-+
-+ /* handle colour twizzle formats, swapping R and B */
-+ if (format == SURFACE_PIXEL_FORMAT_GRPH_BGRA8888 ||
-+ format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 ||
-+ format ==
-+ SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS ||
-+ format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
-+ set_reg_field_value(
-+ value, 2, GRPH_SWAP_CNTL, GRPH_RED_CROSSBAR);
-+ set_reg_field_value(
-+ value, 2, GRPH_SWAP_CNTL, GRPH_BLUE_CROSSBAR);
-+ }
-+
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_SWAP_CNTL),
-+ value);
-+
-+
-+ value = dal_read_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_CONTROL));
-+
-+ switch (format) {
-+ case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
-+ set_reg_field_value(
-+ value, 0, GRPH_CONTROL, GRPH_DEPTH);
-+ set_reg_field_value(
-+ value, 0, GRPH_CONTROL, GRPH_FORMAT);
-+ break;
-+ case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
-+ set_reg_field_value(
-+ value, 1, GRPH_CONTROL, GRPH_DEPTH);
-+ set_reg_field_value(
-+ value, 1, GRPH_CONTROL, GRPH_FORMAT);
-+ break;
-+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
-+ case SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
-+ set_reg_field_value(
-+ value, 2, GRPH_CONTROL, GRPH_DEPTH);
-+ set_reg_field_value(
-+ value, 0, GRPH_CONTROL, GRPH_FORMAT);
-+ break;
-+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
-+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
-+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
-+ set_reg_field_value(
-+ value, 2, GRPH_CONTROL, GRPH_DEPTH);
-+ set_reg_field_value(
-+ value, 1, GRPH_CONTROL, GRPH_FORMAT);
-+ break;
-+ case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
-+ case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
-+ set_reg_field_value(
-+ value, 3, GRPH_CONTROL, GRPH_DEPTH);
-+ set_reg_field_value(
-+ value, 0, GRPH_CONTROL, GRPH_FORMAT);
-+ break;
-+ default:
-+ break;
-+ }
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmGRPH_CONTROL),
-+ value);
-+
-+ /*TODO [hwentlan] MOVE THIS TO CONTROLLER GAMMA!!!!!*/
-+ value = dal_read_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmPRESCALE_GRPH_CONTROL));
-+
-+ if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
-+ set_reg_field_value(
-+ value, 1, PRESCALE_GRPH_CONTROL,
-+ GRPH_PRESCALE_SELECT);
-+ set_reg_field_value(
-+ value, 1, PRESCALE_GRPH_CONTROL,
-+ GRPH_PRESCALE_R_SIGN);
-+ set_reg_field_value(
-+ value, 1, PRESCALE_GRPH_CONTROL,
-+ GRPH_PRESCALE_G_SIGN);
-+ set_reg_field_value(
-+ value, 1, PRESCALE_GRPH_CONTROL,
-+ GRPH_PRESCALE_B_SIGN);
-+ } else {
-+ set_reg_field_value(
-+ value, 0, PRESCALE_GRPH_CONTROL,
-+ GRPH_PRESCALE_SELECT);
-+ set_reg_field_value(
-+ value, 0, PRESCALE_GRPH_CONTROL,
-+ GRPH_PRESCALE_R_SIGN);
-+ set_reg_field_value(
-+ value, 0, PRESCALE_GRPH_CONTROL,
-+ GRPH_PRESCALE_G_SIGN);
-+ set_reg_field_value(
-+ value, 0, PRESCALE_GRPH_CONTROL,
-+ GRPH_PRESCALE_B_SIGN);
-+ }
-+ dal_write_reg(
-+ mem_input110->base.ctx,
-+ DCP_REG(mmPRESCALE_GRPH_CONTROL),
-+ value);
-+ }
-+}
-+
-+bool dce110_mem_input_program_surface_flip_and_addr(
-+ struct mem_input *mem_input,
-+ const struct dc_plane_address *address,
-+ bool flip_immediate)
-+{
-+ struct dce110_mem_input *mem_input110 = TO_DCE110_MEM_INPUT(mem_input);
-+
-+ set_flip_control(mem_input110, flip_immediate);
-+ program_addr(mem_input110,
-+ address);
-+
-+ return true;
-+}
-+
-+bool dce110_mem_input_program_surface_config(
-+ struct mem_input *mem_input,
-+ const struct dc_surface *surface)
-+{
-+ struct dce110_mem_input *mem_input110 = TO_DCE110_MEM_INPUT(mem_input);
-+
-+ enable(mem_input110);
-+ program_tiling(mem_input110, &surface->tiling_info, surface->format);
-+ program_size_and_rotation(mem_input110,
-+ surface->rotation, &surface->plane_size);
-+ program_pixel_format(mem_input110, surface->format);
-+
-+ return true;
-+}
-+
-+static void program_urgency_watermark(
-+ const struct dc_context *ctx,
-+ const uint32_t offset,
-+ struct bw_watermarks marks_low,
-+ uint32_t total_dest_line_time_ns)
-+{
-+ /* register value */
-+ uint32_t urgency_cntl = 0;
-+ uint32_t wm_mask_cntl = 0;
-+
-+ uint32_t urgency_addr = offset + mmDPG_PIPE_URGENCY_CONTROL;
-+ uint32_t wm_addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-+
-+ /*Write mask to enable reading/writing of watermark set A*/
-+ wm_mask_cntl = dal_read_reg(ctx, wm_addr);
-+ set_reg_field_value(wm_mask_cntl,
-+ 1,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ URGENCY_WATERMARK_MASK);
-+ dal_write_reg(ctx, wm_addr, wm_mask_cntl);
-+
-+ urgency_cntl = dal_read_reg(ctx, urgency_addr);
-+
-+ set_reg_field_value(
-+ urgency_cntl,
-+ marks_low.a_mark,
-+ DPG_PIPE_URGENCY_CONTROL,
-+ URGENCY_LOW_WATERMARK);
-+
-+ set_reg_field_value(
-+ urgency_cntl,
-+ total_dest_line_time_ns,
-+ DPG_PIPE_URGENCY_CONTROL,
-+ URGENCY_HIGH_WATERMARK);
-+ dal_write_reg(ctx, urgency_addr, urgency_cntl);
-+
-+
-+ /*Write mask to enable reading/writing of watermark set B*/
-+ wm_mask_cntl = dal_read_reg(ctx, wm_addr);
-+ set_reg_field_value(wm_mask_cntl,
-+ 2,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ URGENCY_WATERMARK_MASK);
-+ dal_write_reg(ctx, wm_addr, wm_mask_cntl);
-+
-+ urgency_cntl = dal_read_reg(ctx, urgency_addr);
-+
-+ set_reg_field_value(urgency_cntl,
-+ marks_low.b_mark,
-+ DPG_PIPE_URGENCY_CONTROL,
-+ URGENCY_LOW_WATERMARK);
-+
-+ set_reg_field_value(urgency_cntl,
-+ total_dest_line_time_ns,
-+ DPG_PIPE_URGENCY_CONTROL,
-+ URGENCY_HIGH_WATERMARK);
-+ dal_write_reg(ctx, urgency_addr, urgency_cntl);
-+}
-+
-+void dce110_program_stutter_watermark(
-+ struct mem_input *mi,
-+ struct bw_watermarks marks)
-+{
-+ const struct dc_context *ctx = mi->ctx;
-+ const uint32_t offset = TO_DCE110_MEM_INPUT(mi)->offsets.dmif;
-+ /* register value */
-+ uint32_t stutter_cntl = 0;
-+ uint32_t wm_mask_cntl = 0;
-+
-+ uint32_t stutter_addr = offset + mmDPG_PIPE_STUTTER_CONTROL;
-+ uint32_t wm_addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-+
-+ /*Write mask to enable reading/writing of watermark set A*/
-+
-+ wm_mask_cntl = dal_read_reg(ctx, wm_addr);
-+ set_reg_field_value(wm_mask_cntl,
-+ 1,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
-+ dal_write_reg(ctx, wm_addr, wm_mask_cntl);
-+
-+ stutter_cntl = dal_read_reg(ctx, stutter_addr);
-+
-+ set_reg_field_value(stutter_cntl,
-+ 1,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_ENABLE);
-+ set_reg_field_value(stutter_cntl,
-+ 1,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_IGNORE_FBC);
-+
-+ /*Write watermark set A*/
-+ set_reg_field_value(stutter_cntl,
-+ marks.a_mark,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_EXIT_SELF_REFRESH_WATERMARK);
-+ dal_write_reg(ctx, stutter_addr, stutter_cntl);
-+
-+ /*Write mask to enable reading/writing of watermark set B*/
-+ wm_mask_cntl = dal_read_reg(ctx, wm_addr);
-+ set_reg_field_value(wm_mask_cntl,
-+ 2,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
-+ dal_write_reg(ctx, wm_addr, wm_mask_cntl);
-+
-+ stutter_cntl = dal_read_reg(ctx, stutter_addr);
-+ set_reg_field_value(stutter_cntl,
-+ 1,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_ENABLE);
-+ set_reg_field_value(stutter_cntl,
-+ 1,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_IGNORE_FBC);
-+
-+ /*Write watermark set B*/
-+ set_reg_field_value(stutter_cntl,
-+ marks.b_mark,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_EXIT_SELF_REFRESH_WATERMARK);
-+ dal_write_reg(ctx, stutter_addr, stutter_cntl);
-+}
-+
-+void dce110_program_nbp_watermark(
-+ struct mem_input *mi,
-+ struct bw_watermarks marks)
-+{
-+ const struct dc_context *ctx = mi->ctx;
-+ const uint32_t offset = TO_DCE110_MEM_INPUT(mi)->offsets.dmif;
-+ uint32_t value;
-+ uint32_t addr;
-+ /* Write mask to enable reading/writing of watermark set A */
-+ addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-+ value = dal_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ NB_PSTATE_CHANGE_WATERMARK_MASK);
-+ dal_write_reg(ctx, addr, value);
-+
-+ addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
-+ value = dal_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_ENABLE);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
-+ dal_write_reg(ctx, addr, value);
-+
-+ /* Write watermark set A */
-+ value = dal_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ marks.a_mark,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_WATERMARK);
-+ dal_write_reg(ctx, addr, value);
-+
-+ /* Write mask to enable reading/writing of watermark set B */
-+ addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-+ value = dal_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ NB_PSTATE_CHANGE_WATERMARK_MASK);
-+ dal_write_reg(ctx, addr, value);
-+
-+ addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
-+ value = dal_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_ENABLE);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
-+ dal_write_reg(ctx, addr, value);
-+
-+ /* Write watermark set B */
-+ value = dal_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ marks.b_mark,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_WATERMARK);
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+void dce110_program_safe_display_marks(struct mem_input *mi)
-+{
-+ struct dce110_mem_input *bm_dce110 = TO_DCE110_MEM_INPUT(mi);
-+ struct bw_watermarks max_marks = { MAX_WATERMARK, MAX_WATERMARK };
-+ struct bw_watermarks nbp_marks = { SAFE_NBP_MARK, SAFE_NBP_MARK };
-+
-+ program_urgency_watermark(
-+ mi->ctx, bm_dce110->offsets.dmif, max_marks, MAX_WATERMARK);
-+ dce110_program_stutter_watermark(mi, max_marks);
-+ dce110_program_nbp_watermark(mi, nbp_marks);
-+
-+}
-+
-+void dce110_program_urgency_watermark(
-+ struct mem_input *mi,
-+ struct bw_watermarks marks,
-+ uint32_t h_total,
-+ uint32_t pixel_clk_in_khz,
-+ uint32_t pstate_blackout_duration_ns)
-+{
-+ struct dce110_mem_input *bm_dce110 = TO_DCE110_MEM_INPUT(mi);
-+ uint32_t total_dest_line_time_ns = 1000000ULL * h_total
-+ / pixel_clk_in_khz + pstate_blackout_duration_ns;
-+
-+ program_urgency_watermark(
-+ mi->ctx,
-+ bm_dce110->offsets.dmif,
-+ marks,
-+ total_dest_line_time_ns);
-+}
-+
-+static uint32_t get_dmif_switch_time_us(struct dc_crtc_timing *timing)
-+{
-+ uint32_t frame_time;
-+ uint32_t pixels_per_second;
-+ uint32_t pixels_per_frame;
-+ uint32_t refresh_rate;
-+ const uint32_t us_in_sec = 1000000;
-+ const uint32_t min_single_frame_time_us = 30000;
-+ /*return double of frame time*/
-+ const uint32_t single_frame_time_multiplier = 2;
-+
-+ if (timing == NULL)
-+ return single_frame_time_multiplier * min_single_frame_time_us;
-+
-+ /*TODO: should we use pixel format normalized pixel clock here?*/
-+ pixels_per_second = timing->pix_clk_khz * 1000;
-+ pixels_per_frame = timing->h_total * timing->v_total;
-+
-+ if (!pixels_per_second || !pixels_per_frame) {
-+ /* avoid division by zero */
-+ ASSERT(pixels_per_frame);
-+ ASSERT(pixels_per_second);
-+ return single_frame_time_multiplier * min_single_frame_time_us;
-+ }
-+
-+ refresh_rate = pixels_per_second / pixels_per_frame;
-+
-+ if (!refresh_rate) {
-+ /* avoid division by zero*/
-+ ASSERT(refresh_rate);
-+ return single_frame_time_multiplier * min_single_frame_time_us;
-+ }
-+
-+ frame_time = us_in_sec / refresh_rate;
-+
-+ if (frame_time < min_single_frame_time_us)
-+ frame_time = min_single_frame_time_us;
-+
-+ frame_time *= single_frame_time_multiplier;
-+
-+ return frame_time;
-+}
-+
-+void dce110_allocate_dmif_buffer(
-+ struct mem_input *mi,
-+ struct dc_crtc_timing *timing,
-+ uint32_t paths_num)
-+{
-+ const uint32_t retry_delay = 10;
-+ uint32_t retry_count = get_dmif_switch_time_us(timing) / retry_delay;
-+
-+ struct dce110_mem_input *bm110 = TO_DCE110_MEM_INPUT(mi);
-+ uint32_t addr = bm110->offsets.pipe + mmPIPE0_DMIF_BUFFER_CONTROL;
-+ uint32_t value;
-+ uint32_t field;
-+
-+ if (bm110->supported_stutter_mode
-+ & STUTTER_MODE_NO_DMIF_BUFFER_ALLOCATION)
-+ goto register_underflow_int;
-+
-+ /*Allocate DMIF buffer*/
-+ value = dal_read_reg(mi->ctx, addr);
-+ field = get_reg_field_value(
-+ value, PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED);
-+ if (field == 2)
-+ goto register_underflow_int;
-+
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ PIPE0_DMIF_BUFFER_CONTROL,
-+ DMIF_BUFFERS_ALLOCATED);
-+
-+ dal_write_reg(mi->ctx, addr, value);
-+
-+ do {
-+ value = dal_read_reg(mi->ctx, addr);
-+ field = get_reg_field_value(
-+ value,
-+ PIPE0_DMIF_BUFFER_CONTROL,
-+ DMIF_BUFFERS_ALLOCATION_COMPLETED);
-+
-+ if (field)
-+ break;
-+
-+ dc_service_delay_in_microseconds(mi->ctx, retry_delay);
-+ retry_count--;
-+
-+ } while (retry_count > 0);
-+
-+ if (field == 0)
-+ dal_logger_write(mi->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s: DMIF allocation failed",
-+ __func__);
-+
-+ /*
-+ * Stella Wong proposed the following change
-+ *
-+ * Value of mcHubRdReqDmifLimit.ENABLE:
-+ * 00 - disable DMIF rdreq limit
-+ * 01 - enable DMIF rdreq limit, disabled by DMIF stall = 1 || urg != 0
-+ * 02 - enable DMIF rdreq limit, disable by DMIF stall = 1
-+ * 03 - force enable DMIF rdreq limit, ignore DMIF stall / urgent
-+ */
-+ addr = mmMC_HUB_RDREQ_DMIF_LIMIT;
-+ value = dal_read_reg(mi->ctx, addr);
-+ if (paths_num > 1)
-+ set_reg_field_value(value, 0, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
-+ else
-+ set_reg_field_value(value, 3, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
-+ dal_write_reg(mi->ctx, addr, value);
-+
-+register_underflow_int:
-+ /*todo*/;
-+ /*register_interrupt(bm110, irq_source, ctrl_id);*/
-+}
-+
-+static void deallocate_dmif_buffer_helper(
-+ struct dc_context *ctx, uint32_t offset)
-+{
-+ uint32_t value;
-+ uint32_t count = 0xBB8; /* max retry count */
-+
-+ value = dal_read_reg(ctx, mmPIPE0_DMIF_BUFFER_CONTROL + offset);
-+
-+ if (!get_reg_field_value(
-+ value, PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED))
-+ return;
-+
-+ set_reg_field_value(
-+ value, 0, PIPE0_DMIF_BUFFER_CONTROL, DMIF_BUFFERS_ALLOCATED);
-+
-+ dal_write_reg(
-+ ctx, mmPIPE0_DMIF_BUFFER_CONTROL + offset, value);
-+
-+ do {
-+ value = dal_read_reg(ctx, mmPIPE0_DMIF_BUFFER_CONTROL + offset);
-+ dc_service_delay_in_microseconds(ctx, 10);
-+ count--;
-+ } while (count > 0 &&
-+ !get_reg_field_value(
-+ value,
-+ PIPE0_DMIF_BUFFER_CONTROL,
-+ DMIF_BUFFERS_ALLOCATION_COMPLETED));
-+}
-+
-+void dce110_deallocate_dmif_buffer(struct mem_input *mi, uint32_t paths_num)
-+{
-+ struct dce110_mem_input *bm_dce110 = TO_DCE110_MEM_INPUT(mi);
-+ uint32_t value;
-+
-+ if (!(bm_dce110->supported_stutter_mode &
-+ STUTTER_MODE_NO_DMIF_BUFFER_ALLOCATION)) {
-+
-+ /* De-allocate DMIF buffer first */
-+ if (mmPIPE0_DMIF_BUFFER_CONTROL + bm_dce110->offsets.pipe != 0)
-+ deallocate_dmif_buffer_helper(
-+ mi->ctx, bm_dce110->offsets.pipe);
-+ }
-+
-+ /* TODO: unregister underflow interrupt
-+ unregisterInterrupt();
-+ */
-+
-+ /* Value of mcHubRdReqDmifLimit.ENABLE.
-+ * 00 - disable dmif rdreq limit
-+ * 01 - enable dmif rdreq limit, disable by dmif stall=1||urg!=0
-+ * 02 - enable dmif rdreq limit, disable by dmif stall=1
-+ * 03 - force enable dmif rdreq limit, ignore dmif stall/urgent
-+ * Stella Wong proposed this change. */
-+ value = dal_read_reg(mi->ctx, mmMC_HUB_RDREQ_DMIF_LIMIT);
-+ if (paths_num > 1)
-+ set_reg_field_value(value, 0, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
-+ else
-+ set_reg_field_value(value, 3, MC_HUB_RDREQ_DMIF_LIMIT, ENABLE);
-+
-+ dal_write_reg(mi->ctx, mmMC_HUB_RDREQ_DMIF_LIMIT, value);
-+}
-+
-+void dce110_program_pix_dur(struct mem_input *mi, uint32_t pix_clk_khz)
-+{
-+ uint64_t pix_dur;
-+ uint32_t addr = mmDMIF_PG0_DPG_PIPE_ARBITRATION_CONTROL1
-+ + TO_DCE110_MEM_INPUT(mi)->offsets.dmif;
-+ uint32_t value = dal_read_reg(mi->ctx, addr);
-+
-+ if (pix_clk_khz == 0)
-+ return;
-+
-+ pix_dur = 1000000000 / pix_clk_khz;
-+
-+ set_reg_field_value(
-+ value,
-+ pix_dur,
-+ DPG_PIPE_ARBITRATION_CONTROL1,
-+ PIXEL_DURATION);
-+
-+ dal_write_reg(mi->ctx, addr, value);
-+}
-+
-+/*****************************************/
-+/* Constructor, Destructor */
-+/*****************************************/
-+
-+bool dce110_mem_input_construct(
-+ struct dce110_mem_input *mem_input110,
-+ struct dc_context *ctx,
-+ uint32_t inst)
-+{
-+ if ((inst < 1) || (inst > ARRAY_SIZE(reg_offsets)))
-+ return false;
-+
-+ mem_input110->base.ctx = ctx;
-+
-+ mem_input110->base.inst = inst;
-+
-+ mem_input110->offsets = reg_offsets[inst - 1];
-+
-+ mem_input110->supported_stutter_mode = 0;
-+ dal_adapter_service_get_feature_value(FEATURE_STUTTER_MODE,
-+ &(mem_input110->supported_stutter_mode),
-+ sizeof(mem_input110->supported_stutter_mode));
-+
-+ return true;
-+}
-+
-+void dce110_mem_input_destroy(struct mem_input **mem_input)
-+{
-+ dc_service_free((*mem_input)->ctx, TO_DCE110_MEM_INPUT(*mem_input));
-+ *mem_input = NULL;
-+}
-+
-+struct mem_input *dce110_mem_input_create(
-+ struct dc_context *ctx,
-+ uint32_t inst)
-+{
-+ struct dce110_mem_input *mem_input110 =
-+ dc_service_alloc(ctx, sizeof(struct dce110_mem_input));
-+
-+ if (!mem_input110)
-+ return NULL;
-+
-+ if (dce110_mem_input_construct(mem_input110,
-+ ctx, inst))
-+ return &mem_input110->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dc_service_free(ctx, mem_input110);
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.h
-new file mode 100644
-index 0000000..9c6d278
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_mem_input.h
-@@ -0,0 +1,88 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_MEM_INPUT_DCE110_H__
-+#define __DC_MEM_INPUT_DCE110_H__
-+
-+#include "inc/mem_input.h"
-+
-+#define TO_DCE110_MEM_INPUT(mi)\
-+ container_of(mi, struct dce110_mem_input, base)
-+
-+struct dce110_mem_input_reg_offsets {
-+ uint32_t dcp;
-+ uint32_t dmif;
-+ uint32_t pipe;
-+};
-+
-+struct dce110_mem_input {
-+ struct mem_input base;
-+ struct dce110_mem_input_reg_offsets offsets;
-+ uint32_t supported_stutter_mode;
-+};
-+
-+struct mem_input *dce110_mem_input_create(
-+ struct dc_context *ctx,
-+ uint32_t inst);
-+
-+void dce110_mem_input_destroy(struct mem_input **mem_input);
-+
-+bool dce110_mem_input_program_surface_flip_and_addr(
-+ struct mem_input *mem_input,
-+ const struct dc_plane_address *address,
-+ bool flip_immediate);
-+
-+bool dce110_mem_input_program_surface_config(
-+ struct mem_input *mem_input,
-+ const struct dc_surface *surface);
-+
-+void dce110_program_nbp_watermark(
-+ struct mem_input *mem_input,
-+ struct bw_watermarks marks);
-+
-+void dce110_program_stutter_watermark(
-+ struct mem_input *mem_input,
-+ struct bw_watermarks marks);
-+
-+void dce110_program_urgency_watermark(
-+ struct mem_input *mem_input,
-+ struct bw_watermarks marks,
-+ uint32_t h_total,
-+ uint32_t pixel_clk_in_khz,
-+ uint32_t pstate_blackout_duration_ns);
-+
-+void dce110_program_safe_display_marks(struct mem_input *mi);
-+
-+void dce110_allocate_dmif_buffer(
-+ struct mem_input *mem_input,
-+ struct dc_crtc_timing *timing,
-+ uint32_t paths_num);
-+
-+void dce110_deallocate_dmif_buffer(
-+ struct mem_input *mem_input, uint32_t paths_num);
-+
-+void dce110_program_pix_dur(
-+ struct mem_input *mem_input, uint32_t pix_clk_khz);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.c
-new file mode 100644
-index 0000000..0fdffac
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.c
-@@ -0,0 +1,296 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/* include DCE11 register header files */
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "dce110_opp.h"
-+
-+#define FROM_OPP(opp)\
-+ container_of(opp, struct dce110_opp, base)
-+
-+enum {
-+ MAX_LUT_ENTRY = 256,
-+ MAX_NUMBER_OF_ENTRIES = 256
-+};
-+
-+static const struct dce110_opp_reg_offsets reg_offsets[] = {
-+{
-+ .fmt_offset = (mmFMT0_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .dcfe_offset = (mmDCFE0_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{ .fmt_offset = (mmFMT1_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .dcfe_offset = (mmDCFE1_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{ .fmt_offset = (mmFMT2_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .dcfe_offset = (mmDCFE2_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+}
-+};
-+
-+static void build_evenly_distributed_points(
-+ struct gamma_pixel *points,
-+ uint32_t numberof_points,
-+ struct fixed31_32 max_value,
-+ struct fixed31_32 divider1,
-+ struct fixed31_32 divider2,
-+ struct fixed31_32 divider3)
-+{
-+ struct gamma_pixel *p = points;
-+ struct gamma_pixel *p_last = p + numberof_points - 1;
-+
-+ uint32_t i = 0;
-+
-+ do {
-+ struct fixed31_32 value = dal_fixed31_32_div_int(
-+ dal_fixed31_32_mul_int(max_value, i),
-+ numberof_points - 1);
-+
-+ p->r = value;
-+ p->g = value;
-+ p->b = value;
-+
-+ ++p;
-+ ++i;
-+ } while (i != numberof_points);
-+
-+ p->r = dal_fixed31_32_div(p_last->r, divider1);
-+ p->g = dal_fixed31_32_div(p_last->g, divider1);
-+ p->b = dal_fixed31_32_div(p_last->b, divider1);
-+
-+ ++p;
-+
-+ p->r = dal_fixed31_32_div(p_last->r, divider2);
-+ p->g = dal_fixed31_32_div(p_last->g, divider2);
-+ p->b = dal_fixed31_32_div(p_last->b, divider2);
-+
-+ ++p;
-+
-+ p->r = dal_fixed31_32_div(p_last->r, divider3);
-+ p->g = dal_fixed31_32_div(p_last->g, divider3);
-+ p->b = dal_fixed31_32_div(p_last->b, divider3);
-+}
-+
-+/*****************************************/
-+/* Constructor, Destructor */
-+/*****************************************/
-+
-+bool dce110_opp_construct(struct dce110_opp *opp110,
-+ struct dc_context *ctx,
-+ uint32_t inst)
-+{
-+ if ((inst < 1) || (inst > ARRAY_SIZE(reg_offsets)))
-+ return false;
-+
-+ opp110->base.ctx = ctx;
-+
-+ opp110->base.inst = inst;
-+
-+ opp110->offsets = reg_offsets[inst - 1];
-+
-+ opp110->regamma.hw_points_num = 128;
-+ opp110->regamma.coordinates_x = NULL;
-+ opp110->regamma.rgb_resulted = NULL;
-+ opp110->regamma.rgb_regamma = NULL;
-+ opp110->regamma.coeff128 = NULL;
-+ opp110->regamma.coeff128_oem = NULL;
-+ opp110->regamma.coeff128_dx = NULL;
-+ opp110->regamma.axis_x_256 = NULL;
-+ opp110->regamma.axis_x_1025 = NULL;
-+ opp110->regamma.rgb_oem = NULL;
-+ opp110->regamma.rgb_user = NULL;
-+ opp110->regamma.extra_points = 3;
-+ opp110->regamma.use_half_points = false;
-+ opp110->regamma.x_max1 = dal_fixed31_32_one;
-+ opp110->regamma.x_max2 = dal_fixed31_32_from_int(2);
-+ opp110->regamma.x_min = dal_fixed31_32_zero;
-+ opp110->regamma.divider1 = dal_fixed31_32_from_fraction(3, 2);
-+ opp110->regamma.divider2 = dal_fixed31_32_from_int(2);
-+ opp110->regamma.divider3 = dal_fixed31_32_from_fraction(5, 2);
-+
-+ opp110->regamma.rgb_user = dc_service_alloc(
-+ ctx,
-+ sizeof(struct pwl_float_data) *
-+ (DX_GAMMA_RAMP_MAX + opp110->regamma.extra_points));
-+ if (!opp110->regamma.rgb_user)
-+ goto failure_1;
-+
-+ opp110->regamma.rgb_oem = dc_service_alloc(
-+ ctx,
-+ sizeof(struct pwl_float_data) *
-+ (DX_GAMMA_RAMP_MAX + opp110->regamma.extra_points));
-+ if (!opp110->regamma.rgb_oem)
-+ goto failure_2;
-+
-+ opp110->regamma.rgb_resulted = dc_service_alloc(
-+ ctx,
-+ sizeof(struct pwl_result_data) *
-+ (MAX_NUMBER_OF_ENTRIES + opp110->regamma.extra_points));
-+ if (!opp110->regamma.rgb_resulted)
-+ goto failure_3;
-+
-+ opp110->regamma.rgb_regamma = dc_service_alloc(
-+ ctx,
-+ sizeof(struct pwl_float_data_ex) *
-+ (MAX_NUMBER_OF_ENTRIES + opp110->regamma.extra_points));
-+ if (!opp110->regamma.rgb_regamma)
-+ goto failure_4;
-+
-+ opp110->regamma.coordinates_x = dc_service_alloc(
-+ ctx,
-+ sizeof(struct hw_x_point) *
-+ (MAX_NUMBER_OF_ENTRIES + opp110->regamma.extra_points));
-+ if (!opp110->regamma.coordinates_x)
-+ goto failure_5;
-+
-+ opp110->regamma.axis_x_256 = dc_service_alloc(
-+ ctx,
-+ sizeof(struct gamma_pixel) *
-+ (MAX_LUT_ENTRY + opp110->regamma.extra_points));
-+ if (!opp110->regamma.axis_x_256)
-+ goto failure_6;
-+
-+ opp110->regamma.axis_x_1025 = dc_service_alloc(
-+ ctx,
-+ sizeof(struct gamma_pixel) *
-+ (DX_GAMMA_RAMP_MAX + opp110->regamma.extra_points));
-+ if (!opp110->regamma.axis_x_1025)
-+ goto failure_7;
-+
-+ opp110->regamma.coeff128 = dc_service_alloc(
-+ ctx,
-+ sizeof(struct pixel_gamma_point) *
-+ (MAX_NUMBER_OF_ENTRIES + opp110->regamma.extra_points));
-+ if (!opp110->regamma.coeff128)
-+ goto failure_8;
-+
-+ opp110->regamma.coeff128_oem = dc_service_alloc(
-+ ctx,
-+ sizeof(struct pixel_gamma_point) *
-+ (MAX_NUMBER_OF_ENTRIES + opp110->regamma.extra_points));
-+ if (!opp110->regamma.coeff128_oem)
-+ goto failure_9;
-+
-+ opp110->regamma.coeff128_dx = dc_service_alloc(
-+ ctx,
-+ sizeof(struct pixel_gamma_point) *
-+ (MAX_NUMBER_OF_ENTRIES + opp110->regamma.extra_points));
-+ if (!opp110->regamma.coeff128_dx)
-+ goto failure_10;
-+
-+ /* init palette */
-+ {
-+ uint32_t i = 0;
-+
-+ do {
-+ opp110->regamma.saved_palette[i].red = (uint8_t)i;
-+ opp110->regamma.saved_palette[i].green = (uint8_t)i;
-+ opp110->regamma.saved_palette[i].blue = (uint8_t)i;
-+
-+ ++i;
-+ } while (i != MAX_LUT_ENTRY);
-+ }
-+
-+ build_evenly_distributed_points(
-+ opp110->regamma.axis_x_256,
-+ MAX_LUT_ENTRY,
-+ opp110->regamma.x_max1,
-+ opp110->regamma.divider1,
-+ opp110->regamma.divider2,
-+ opp110->regamma.divider3);
-+
-+ build_evenly_distributed_points(
-+ opp110->regamma.axis_x_1025,
-+ DX_GAMMA_RAMP_MAX,
-+ opp110->regamma.x_max1,
-+ opp110->regamma.divider1,
-+ opp110->regamma.divider2,
-+ opp110->regamma.divider3);
-+
-+ return true;
-+
-+failure_10:
-+ dc_service_free(ctx, opp110->regamma.coeff128_oem);
-+failure_9:
-+ dc_service_free(ctx, opp110->regamma.coeff128);
-+failure_8:
-+ dc_service_free(ctx, opp110->regamma.axis_x_1025);
-+failure_7:
-+ dc_service_free(ctx, opp110->regamma.axis_x_256);
-+failure_6:
-+ dc_service_free(ctx, opp110->regamma.coordinates_x);
-+failure_5:
-+ dc_service_free(ctx, opp110->regamma.rgb_regamma);
-+failure_4:
-+ dc_service_free(ctx, opp110->regamma.rgb_resulted);
-+failure_3:
-+ dc_service_free(ctx, opp110->regamma.rgb_oem);
-+failure_2:
-+ dc_service_free(ctx, opp110->regamma.rgb_user);
-+failure_1:
-+
-+ return true;
-+}
-+
-+void dce110_opp_destroy(struct output_pixel_processor **opp)
-+{
-+ dc_service_free((*opp)->ctx, FROM_OPP(*opp)->regamma.coeff128_dx);
-+ dc_service_free((*opp)->ctx, FROM_OPP(*opp)->regamma.coeff128_oem);
-+ dc_service_free((*opp)->ctx, FROM_OPP(*opp)->regamma.coeff128);
-+ dc_service_free((*opp)->ctx, FROM_OPP(*opp)->regamma.axis_x_1025);
-+ dc_service_free((*opp)->ctx, FROM_OPP(*opp)->regamma.axis_x_256);
-+ dc_service_free((*opp)->ctx, FROM_OPP(*opp)->regamma.coordinates_x);
-+ dc_service_free((*opp)->ctx, FROM_OPP(*opp)->regamma.rgb_regamma);
-+ dc_service_free((*opp)->ctx, FROM_OPP(*opp)->regamma.rgb_resulted);
-+ dc_service_free((*opp)->ctx, FROM_OPP(*opp)->regamma.rgb_oem);
-+ dc_service_free((*opp)->ctx, FROM_OPP(*opp)->regamma.rgb_user);
-+ dc_service_free((*opp)->ctx, FROM_OPP(*opp));
-+ *opp = NULL;
-+}
-+
-+struct output_pixel_processor *dce110_opp_create(
-+ struct dc_context *ctx,
-+ uint32_t inst)
-+{
-+ struct dce110_opp *opp =
-+ dc_service_alloc(ctx, sizeof(struct dce110_opp));
-+
-+ if (!opp)
-+ return NULL;
-+
-+ if (dce110_opp_construct(opp,
-+ ctx, inst))
-+ return &opp->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dc_service_free(ctx, opp);
-+ return NULL;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.h
-new file mode 100644
-index 0000000..71fe624
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.h
-@@ -0,0 +1,140 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_OPP_DCE110_H__
-+#define __DC_OPP_DCE110_H__
-+
-+#include "dc_types.h"
-+#include "inc/opp.h"
-+
-+enum dce110_opp_reg_type {
-+ DCE110_OPP_REG_DCP = 0,
-+ DCE110_OPP_REG_DCFE,
-+ DCE110_OPP_REG_FMT,
-+
-+ DCE110_OPP_REG_MAX
-+};
-+
-+struct dce110_regamma {
-+ struct gamma_curve arr_curve_points[16];
-+ struct curve_points arr_points[3];
-+ uint32_t hw_points_num;
-+ struct hw_x_point *coordinates_x;
-+ struct pwl_result_data *rgb_resulted;
-+
-+ /* re-gamma curve */
-+ struct pwl_float_data_ex *rgb_regamma;
-+ /* coeff used to map user evenly distributed points
-+ * to our hardware points (predefined) for gamma 256 */
-+ struct pixel_gamma_point *coeff128;
-+ struct pixel_gamma_point *coeff128_oem;
-+ /* coeff used to map user evenly distributed points
-+ * to our hardware points (predefined) for gamma 1025 */
-+ struct pixel_gamma_point *coeff128_dx;
-+ /* evenly distributed points, gamma 256 software points 0-255 */
-+ struct gamma_pixel *axis_x_256;
-+ /* evenly distributed points, gamma 1025 software points 0-1025 */
-+ struct gamma_pixel *axis_x_1025;
-+ /* OEM supplied gamma for regamma LUT */
-+ struct pwl_float_data *rgb_oem;
-+ /* user supplied gamma */
-+ struct pwl_float_data *rgb_user;
-+ struct dev_c_lut saved_palette[RGB_256X3X16];
-+ uint32_t extra_points;
-+ bool use_half_points;
-+ struct fixed31_32 x_max1;
-+ struct fixed31_32 x_max2;
-+ struct fixed31_32 x_min;
-+ struct fixed31_32 divider1;
-+ struct fixed31_32 divider2;
-+ struct fixed31_32 divider3;
-+};
-+
-+/* OPP RELATED */
-+#define TO_DCE110_OPP(opp)\
-+ container_of(opp, struct dce110_opp, base)
-+
-+struct dce110_opp_reg_offsets {
-+ uint32_t fmt_offset;
-+ uint32_t dcp_offset;
-+ uint32_t dcfe_offset;
-+};
-+
-+struct dce110_opp {
-+ struct output_pixel_processor base;
-+ struct dce110_opp_reg_offsets offsets;
-+ struct dce110_regamma regamma;
-+};
-+
-+bool dce110_opp_construct(struct dce110_opp *opp110,
-+ struct dc_context *ctx,
-+ uint32_t inst);
-+
-+void dce110_opp_destroy(struct output_pixel_processor **opp);
-+
-+struct output_pixel_processor *dce110_opp_create(
-+ struct dc_context *ctx,
-+ uint32_t inst);
-+
-+/* REGAMMA RELATED */
-+void dce110_opp_power_on_regamma_lut(
-+ struct output_pixel_processor *opp,
-+ bool power_on);
-+
-+bool dce110_opp_set_regamma(
-+ struct output_pixel_processor *opp,
-+ const struct gamma_ramp *ramp,
-+ const struct gamma_parameters *params,
-+ bool force_bypass);
-+
-+bool dce110_opp_map_legacy_and_regamma_hw_to_x_user(
-+ struct output_pixel_processor *opp,
-+ const struct gamma_ramp *gamma_ramp,
-+ const struct gamma_parameters *params);
-+
-+void dce110_opp_set_csc_adjustment(
-+ struct output_pixel_processor *opp,
-+ const struct grph_csc_adjustment *adjust);
-+
-+void dce110_opp_set_csc_default(
-+ struct output_pixel_processor *opp,
-+ const struct default_adjustment *default_adjust);
-+
-+/* FORMATTER RELATED */
-+void dce110_opp_program_bit_depth_reduction(
-+ struct output_pixel_processor *opp,
-+ const struct bit_depth_reduction_params *params);
-+
-+void dce110_opp_program_clamping_and_pixel_encoding(
-+ struct output_pixel_processor *opp,
-+ const struct clamping_and_pixel_encoding_params *params);
-+
-+
-+void dce110_opp_set_dyn_expansion(
-+ struct output_pixel_processor *opp,
-+ enum color_space color_sp,
-+ enum dc_color_depth color_dpth,
-+ enum signal_type signal);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_csc.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_csc.c
-new file mode 100644
-index 0000000..91430c0
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_csc.c
-@@ -0,0 +1,904 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "dce110_opp.h"
-+#include "basics/conversion.h"
-+
-+/* include DCE11 register header files */
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#define DCP_REG(reg)\
-+ (reg + opp110->offsets.dcp_offset)
-+
-+enum {
-+ OUTPUT_CSC_MATRIX_SIZE = 12
-+};
-+
-+struct out_csc_color_matrix {
-+ enum color_space color_space;
-+ uint16_t regval[OUTPUT_CSC_MATRIX_SIZE];
-+};
-+
-+static const struct out_csc_color_matrix global_color_matrix[] = {
-+{ COLOR_SPACE_SRGB_FULL_RANGE,
-+ { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
-+{ COLOR_SPACE_SRGB_LIMITED_RANGE,
-+ { 0x1B60, 0, 0, 0x200, 0, 0x1B60, 0, 0x200, 0, 0, 0x1B60, 0x200} },
-+{ COLOR_SPACE_YCBCR601,
-+ { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x82F, 0x1012, 0x31F, 0x200, 0xFB47,
-+ 0xF6B9, 0xE00, 0x1000} },
-+{ COLOR_SPACE_YCBCR709, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x5D2, 0x1394, 0x1FA,
-+ 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
-+/* YOnly same as YCbCr709 but Y in Full range -To do. */
-+{ COLOR_SPACE_YCBCR601_YONLY, { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
-+ 0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
-+{ COLOR_SPACE_YCBCR709_YONLY, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
-+ 0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }
-+};
-+
-+enum csc_color_mode {
-+ /* 00 - BITS2:0 Bypass */
-+ CSC_COLOR_MODE_GRAPHICS_BYPASS,
-+ /* 01 - hard coded coefficient TV RGB */
-+ CSC_COLOR_MODE_GRAPHICS_PREDEFINED,
-+ /* 04 - programmable OUTPUT CSC coefficient */
-+ CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC,
-+};
-+
-+static void program_color_matrix(
-+ struct dce110_opp *opp110,
-+ const struct out_csc_color_matrix *tbl_entry,
-+ enum grph_color_adjust_option options)
-+{
-+ struct dc_context *ctx = opp110->base.ctx;
-+ {
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmOUTPUT_CSC_C11_C12);
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ value,
-+ tbl_entry->regval[0],
-+ OUTPUT_CSC_C11_C12,
-+ OUTPUT_CSC_C11);
-+
-+ set_reg_field_value(
-+ value,
-+ tbl_entry->regval[1],
-+ OUTPUT_CSC_C11_C12,
-+ OUTPUT_CSC_C12);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+ {
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmOUTPUT_CSC_C13_C14);
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ value,
-+ tbl_entry->regval[2],
-+ OUTPUT_CSC_C13_C14,
-+ OUTPUT_CSC_C13);
-+ /* fixed S0.13 format */
-+ set_reg_field_value(
-+ value,
-+ tbl_entry->regval[3],
-+ OUTPUT_CSC_C13_C14,
-+ OUTPUT_CSC_C14);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+ {
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmOUTPUT_CSC_C21_C22);
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ value,
-+ tbl_entry->regval[4],
-+ OUTPUT_CSC_C21_C22,
-+ OUTPUT_CSC_C21);
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ value,
-+ tbl_entry->regval[5],
-+ OUTPUT_CSC_C21_C22,
-+ OUTPUT_CSC_C22);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+ {
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmOUTPUT_CSC_C23_C24);
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ value,
-+ tbl_entry->regval[6],
-+ OUTPUT_CSC_C23_C24,
-+ OUTPUT_CSC_C23);
-+ /* fixed S0.13 format */
-+ set_reg_field_value(
-+ value,
-+ tbl_entry->regval[7],
-+ OUTPUT_CSC_C23_C24,
-+ OUTPUT_CSC_C24);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+ {
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmOUTPUT_CSC_C31_C32);
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ value,
-+ tbl_entry->regval[8],
-+ OUTPUT_CSC_C31_C32,
-+ OUTPUT_CSC_C31);
-+ /* fixed S0.13 format */
-+ set_reg_field_value(
-+ value,
-+ tbl_entry->regval[9],
-+ OUTPUT_CSC_C31_C32,
-+ OUTPUT_CSC_C32);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+ {
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmOUTPUT_CSC_C33_C34);
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ value,
-+ tbl_entry->regval[10],
-+ OUTPUT_CSC_C33_C34,
-+ OUTPUT_CSC_C33);
-+ /* fixed S0.13 format */
-+ set_reg_field_value(
-+ value,
-+ tbl_entry->regval[11],
-+ OUTPUT_CSC_C33_C34,
-+ OUTPUT_CSC_C34);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+}
-+
-+/*
-+ * initialize_color_float_adj_reference_values
-+ * This initialize display color adjust input from API to HW range for later
-+ * calculation use. This is shared by all the display color adjustment.
-+ * @param :
-+ * @return None
-+ */
-+static void initialize_color_float_adj_reference_values(
-+ const struct grph_csc_adjustment *adjust,
-+ struct fixed31_32 *grph_cont,
-+ struct fixed31_32 *grph_sat,
-+ struct fixed31_32 *grph_bright,
-+ struct fixed31_32 *sin_grph_hue,
-+ struct fixed31_32 *cos_grph_hue)
-+{
-+ /* Hue adjustment could be negative. -45 ~ +45 */
-+ struct fixed31_32 hue =
-+ dal_fixed31_32_mul(
-+ dal_fixed31_32_from_fraction(adjust->grph_hue, 180),
-+ dal_fixed31_32_pi);
-+
-+ *sin_grph_hue = dal_fixed31_32_sin(hue);
-+ *cos_grph_hue = dal_fixed31_32_cos(hue);
-+
-+ if (adjust->adjust_divider) {
-+ *grph_cont =
-+ dal_fixed31_32_from_fraction(
-+ adjust->grph_cont,
-+ adjust->adjust_divider);
-+ *grph_sat =
-+ dal_fixed31_32_from_fraction(
-+ adjust->grph_sat,
-+ adjust->adjust_divider);
-+ *grph_bright =
-+ dal_fixed31_32_from_fraction(
-+ adjust->grph_bright,
-+ adjust->adjust_divider);
-+ } else {
-+ *grph_cont = dal_fixed31_32_from_int(adjust->grph_cont);
-+ *grph_sat = dal_fixed31_32_from_int(adjust->grph_sat);
-+ *grph_bright = dal_fixed31_32_from_int(adjust->grph_bright);
-+ }
-+}
-+
-+static inline struct fixed31_32 fixed31_32_clamp(
-+ struct fixed31_32 value,
-+ int32_t min_numerator,
-+ int32_t max_numerator,
-+ int32_t denominator)
-+{
-+ return dal_fixed31_32_clamp(
-+ value,
-+ dal_fixed31_32_from_fraction(
-+ min_numerator,
-+ denominator),
-+ dal_fixed31_32_from_fraction(
-+ max_numerator,
-+ denominator));
-+}
-+
-+static void setup_reg_format(
-+ struct fixed31_32 *coefficients,
-+ uint16_t *reg_values)
-+{
-+ enum {
-+ LENGTH = 12,
-+ DENOMINATOR = 10000
-+ };
-+
-+ static const int32_t min_numerator[] = {
-+ -3 * DENOMINATOR,
-+ -DENOMINATOR
-+ };
-+
-+ static const int32_t max_numerator[] = {
-+ DENOMINATOR,
-+ DENOMINATOR
-+ };
-+
-+ static const uint8_t integer_bits[] = { 2, 0 };
-+
-+ uint32_t i = 0;
-+
-+ do {
-+ const uint32_t index = (i % 4) == 3;
-+
-+ reg_values[i] = fixed_point_to_int_frac(
-+ fixed31_32_clamp(coefficients[(i + 8) % LENGTH],
-+ min_numerator[index],
-+ max_numerator[index],
-+ DENOMINATOR),
-+ integer_bits[index], 13);
-+
-+ ++i;
-+ } while (i != LENGTH);
-+}
-+
-+/**
-+ *****************************************************************************
-+ * Function: setup_adjustments
-+ * @note prepare to setup the values
-+ *
-+ * @see
-+ *
-+ *****************************************************************************
-+ */
-+static void setup_adjustments(const struct grph_csc_adjustment *adjust,
-+ struct dc_csc_adjustments *adjustments)
-+{
-+ if (adjust->adjust_divider != 0) {
-+ adjustments->brightness =
-+ dal_fixed31_32_from_fraction(adjust->grph_bright,
-+ adjust->adjust_divider);
-+ adjustments->contrast =
-+ dal_fixed31_32_from_fraction(adjust->grph_cont,
-+ adjust->adjust_divider);
-+ adjustments->saturation =
-+ dal_fixed31_32_from_fraction(adjust->grph_sat,
-+ adjust->adjust_divider);
-+ } else {
-+ adjustments->brightness =
-+ dal_fixed31_32_from_fraction(adjust->grph_bright, 1);
-+ adjustments->contrast =
-+ dal_fixed31_32_from_fraction(adjust->grph_cont, 1);
-+ adjustments->saturation =
-+ dal_fixed31_32_from_fraction(adjust->grph_sat, 1);
-+ }
-+
-+ /* convert degrees into radians */
-+ adjustments->hue =
-+ dal_fixed31_32_mul(
-+ dal_fixed31_32_from_fraction(adjust->grph_hue, 180),
-+ dal_fixed31_32_pi);
-+}
-+
-+static void prepare_tv_rgb_ideal(
-+ struct fixed31_32 *matrix)
-+{
-+ static const int32_t matrix_[] = {
-+ 85546875, 0, 0, 6250000,
-+ 0, 85546875, 0, 6250000,
-+ 0, 0, 85546875, 6250000
-+ };
-+
-+ uint32_t i = 0;
-+
-+ do {
-+ matrix[i] = dal_fixed31_32_from_fraction(
-+ matrix_[i],
-+ 100000000);
-+ ++i;
-+ } while (i != ARRAY_SIZE(matrix_));
-+}
-+
-+/**
-+ *****************************************************************************
-+ * Function: dal_transform_wide_gamut_set_rgb_adjustment_legacy
-+ *
-+ * @param [in] const struct grph_csc_adjustment *adjust
-+ *
-+ * @return
-+ * void
-+ *
-+ * @note calculate and program color adjustments for sRGB color space
-+ *
-+ * @see
-+ *
-+ *****************************************************************************
-+ */
-+static void set_rgb_adjustment_legacy(
-+ struct dce110_opp *opp110,
-+ const struct grph_csc_adjustment *adjust)
-+{
-+ const struct fixed31_32 k1 =
-+ dal_fixed31_32_from_fraction(701000, 1000000);
-+ const struct fixed31_32 k2 =
-+ dal_fixed31_32_from_fraction(236568, 1000000);
-+ const struct fixed31_32 k3 =
-+ dal_fixed31_32_from_fraction(-587000, 1000000);
-+ const struct fixed31_32 k4 =
-+ dal_fixed31_32_from_fraction(464432, 1000000);
-+ const struct fixed31_32 k5 =
-+ dal_fixed31_32_from_fraction(-114000, 1000000);
-+ const struct fixed31_32 k6 =
-+ dal_fixed31_32_from_fraction(-701000, 1000000);
-+ const struct fixed31_32 k7 =
-+ dal_fixed31_32_from_fraction(-299000, 1000000);
-+ const struct fixed31_32 k8 =
-+ dal_fixed31_32_from_fraction(-292569, 1000000);
-+ const struct fixed31_32 k9 =
-+ dal_fixed31_32_from_fraction(413000, 1000000);
-+ const struct fixed31_32 k10 =
-+ dal_fixed31_32_from_fraction(-92482, 1000000);
-+ const struct fixed31_32 k11 =
-+ dal_fixed31_32_from_fraction(-114000, 1000000);
-+ const struct fixed31_32 k12 =
-+ dal_fixed31_32_from_fraction(385051, 1000000);
-+ const struct fixed31_32 k13 =
-+ dal_fixed31_32_from_fraction(-299000, 1000000);
-+ const struct fixed31_32 k14 =
-+ dal_fixed31_32_from_fraction(886000, 1000000);
-+ const struct fixed31_32 k15 =
-+ dal_fixed31_32_from_fraction(-587000, 1000000);
-+ const struct fixed31_32 k16 =
-+ dal_fixed31_32_from_fraction(-741914, 1000000);
-+ const struct fixed31_32 k17 =
-+ dal_fixed31_32_from_fraction(886000, 1000000);
-+ const struct fixed31_32 k18 =
-+ dal_fixed31_32_from_fraction(-144086, 1000000);
-+
-+ const struct fixed31_32 luma_r =
-+ dal_fixed31_32_from_fraction(299, 1000);
-+ const struct fixed31_32 luma_g =
-+ dal_fixed31_32_from_fraction(587, 1000);
-+ const struct fixed31_32 luma_b =
-+ dal_fixed31_32_from_fraction(114, 1000);
-+
-+ struct out_csc_color_matrix tbl_entry;
-+ struct fixed31_32 matrix[OUTPUT_CSC_MATRIX_SIZE];
-+
-+ struct fixed31_32 grph_cont;
-+ struct fixed31_32 grph_sat;
-+ struct fixed31_32 grph_bright;
-+ struct fixed31_32 sin_grph_hue;
-+ struct fixed31_32 cos_grph_hue;
-+
-+ initialize_color_float_adj_reference_values(
-+ adjust, &grph_cont, &grph_sat,
-+ &grph_bright, &sin_grph_hue, &cos_grph_hue);
-+
-+ /* COEF_1_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 +
-+ * Sin(GrphHue) * K2)) */
-+ /* (Cos(GrphHue) * K1 + Sin(GrphHue) * K2) */
-+ matrix[0] =
-+ dal_fixed31_32_add(
-+ dal_fixed31_32_mul(cos_grph_hue, k1),
-+ dal_fixed31_32_mul(sin_grph_hue, k2));
-+ /* GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2 */
-+ matrix[0] = dal_fixed31_32_mul(grph_sat, matrix[0]);
-+ /* (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)) */
-+ matrix[0] = dal_fixed31_32_add(luma_r, matrix[0]);
-+ /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) *
-+ * K2)) */
-+ matrix[0] = dal_fixed31_32_mul(grph_cont, matrix[0]);
-+
-+ /* COEF_1_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 +
-+ * Sin(GrphHue) * K4)) */
-+ /* (Cos(GrphHue) * K3 + Sin(GrphHue) * K4) */
-+ matrix[1] =
-+ dal_fixed31_32_add(
-+ dal_fixed31_32_mul(cos_grph_hue, k3),
-+ dal_fixed31_32_mul(sin_grph_hue, k4));
-+ /* GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4) */
-+ matrix[1] = dal_fixed31_32_mul(grph_sat, matrix[1]);
-+ /* (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)) */
-+ matrix[1] = dal_fixed31_32_add(luma_g, matrix[1]);
-+ /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) *
-+ * K4)) */
-+ matrix[1] = dal_fixed31_32_mul(grph_cont, matrix[1]);
-+
-+ /* COEF_1_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 +
-+ * Sin(GrphHue) * K6)) */
-+ /* (Cos(GrphHue) * K5 + Sin(GrphHue) * K6) */
-+ matrix[2] =
-+ dal_fixed31_32_add(
-+ dal_fixed31_32_mul(cos_grph_hue, k5),
-+ dal_fixed31_32_mul(sin_grph_hue, k6));
-+ /* GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6) */
-+ matrix[2] = dal_fixed31_32_mul(grph_sat, matrix[2]);
-+ /* LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6) */
-+ matrix[2] = dal_fixed31_32_add(luma_b, matrix[2]);
-+ /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) *
-+ * K6)) */
-+ matrix[2] = dal_fixed31_32_mul(grph_cont, matrix[2]);
-+
-+ /* COEF_1_4 = GrphBright */
-+ matrix[3] = grph_bright;
-+
-+ /* COEF_2_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 +
-+ * Sin(GrphHue) * K8)) */
-+ /* (Cos(GrphHue) * K7 + Sin(GrphHue) * K8) */
-+ matrix[4] =
-+ dal_fixed31_32_add(
-+ dal_fixed31_32_mul(cos_grph_hue, k7),
-+ dal_fixed31_32_mul(sin_grph_hue, k8));
-+ /* GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8) */
-+ matrix[4] = dal_fixed31_32_mul(grph_sat, matrix[4]);
-+ /* (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)) */
-+ matrix[4] = dal_fixed31_32_add(luma_r, matrix[4]);
-+ /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) *
-+ * K8)) */
-+ matrix[4] = dal_fixed31_32_mul(grph_cont, matrix[4]);
-+
-+ /* COEF_2_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 +
-+ * Sin(GrphHue) * K10)) */
-+ /* (Cos(GrphHue) * K9 + Sin(GrphHue) * K10)) */
-+ matrix[5] =
-+ dal_fixed31_32_add(
-+ dal_fixed31_32_mul(cos_grph_hue, k9),
-+ dal_fixed31_32_mul(sin_grph_hue, k10));
-+ /* GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10)) */
-+ matrix[5] = dal_fixed31_32_mul(grph_sat, matrix[5]);
-+ /* (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10)) */
-+ matrix[5] = dal_fixed31_32_add(luma_g, matrix[5]);
-+ /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) *
-+ * K10)) */
-+ matrix[5] = dal_fixed31_32_mul(grph_cont, matrix[5]);
-+
-+ /* COEF_2_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 +
-+ * Sin(GrphHue) * K12)) */
-+ /* (Cos(GrphHue) * K11 + Sin(GrphHue) * K12)) */
-+ matrix[6] =
-+ dal_fixed31_32_add(
-+ dal_fixed31_32_mul(cos_grph_hue, k11),
-+ dal_fixed31_32_mul(sin_grph_hue, k12));
-+ /* GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12)) */
-+ matrix[6] = dal_fixed31_32_mul(grph_sat, matrix[6]);
-+ /* (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12)) */
-+ matrix[6] = dal_fixed31_32_add(luma_b, matrix[6]);
-+ /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) *
-+ * K12)) */
-+ matrix[6] = dal_fixed31_32_mul(grph_cont, matrix[6]);
-+
-+ /* COEF_2_4 = GrphBright */
-+ matrix[7] = grph_bright;
-+
-+ /* COEF_3_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +
-+ * Sin(GrphHue) * K14)) */
-+ /* (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
-+ matrix[8] =
-+ dal_fixed31_32_add(
-+ dal_fixed31_32_mul(cos_grph_hue, k13),
-+ dal_fixed31_32_mul(sin_grph_hue, k14));
-+ /* GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
-+ matrix[8] = dal_fixed31_32_mul(grph_sat, matrix[8]);
-+ /* (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
-+ matrix[8] = dal_fixed31_32_add(luma_r, matrix[8]);
-+ /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) *
-+ * K14)) */
-+ matrix[8] = dal_fixed31_32_mul(grph_cont, matrix[8]);
-+
-+ /* COEF_3_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 +
-+ * Sin(GrphHue) * K16)) */
-+ /* GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16) */
-+ matrix[9] =
-+ dal_fixed31_32_add(
-+ dal_fixed31_32_mul(cos_grph_hue, k15),
-+ dal_fixed31_32_mul(sin_grph_hue, k16));
-+ /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
-+ matrix[9] = dal_fixed31_32_mul(grph_sat, matrix[9]);
-+ /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
-+ matrix[9] = dal_fixed31_32_add(luma_g, matrix[9]);
-+ /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) *
-+ * K16)) */
-+ matrix[9] = dal_fixed31_32_mul(grph_cont, matrix[9]);
-+
-+ /* COEF_3_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 +
-+ * Sin(GrphHue) * K18)) */
-+ /* (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
-+ matrix[10] =
-+ dal_fixed31_32_add(
-+ dal_fixed31_32_mul(cos_grph_hue, k17),
-+ dal_fixed31_32_mul(sin_grph_hue, k18));
-+ /* GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
-+ matrix[10] = dal_fixed31_32_mul(grph_sat, matrix[10]);
-+ /* (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
-+ matrix[10] = dal_fixed31_32_add(luma_b, matrix[10]);
-+ /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) *
-+ * K18)) */
-+ matrix[10] = dal_fixed31_32_mul(grph_cont, matrix[10]);
-+
-+ /* COEF_3_4 = GrphBright */
-+ matrix[11] = grph_bright;
-+
-+ tbl_entry.color_space = adjust->c_space;
-+
-+ convert_float_matrix(tbl_entry.regval, matrix, OUTPUT_CSC_MATRIX_SIZE);
-+
-+ program_color_matrix(
-+ opp110, &tbl_entry, adjust->color_adjust_option);
-+}
-+
-+/**
-+ *****************************************************************************
-+ * Function: dal_transform_wide_gamut_set_rgb_limited_range_adjustment
-+ *
-+ * @param [in] const struct grph_csc_adjustment *adjust
-+ *
-+ * @return
-+ * void
-+ *
-+ * @note calculate and program color adjustments for sRGB limited color space
-+ *
-+ * @see
-+ *
-+ *****************************************************************************
-+ */
-+static void set_rgb_limited_range_adjustment(
-+ struct dce110_opp *opp110,
-+ const struct grph_csc_adjustment *adjust)
-+{
-+ struct out_csc_color_matrix reg_matrix;
-+ struct fixed31_32 change_matrix[OUTPUT_CSC_MATRIX_SIZE];
-+ struct fixed31_32 matrix[OUTPUT_CSC_MATRIX_SIZE];
-+ struct dc_csc_adjustments adjustments;
-+ struct fixed31_32 ideals[OUTPUT_CSC_MATRIX_SIZE];
-+
-+ prepare_tv_rgb_ideal(ideals);
-+
-+ setup_adjustments(adjust, &adjustments);
-+
-+ calculate_adjustments(ideals, &adjustments, matrix);
-+
-+ dc_service_memmove(change_matrix, matrix, sizeof(matrix));
-+
-+ /* from 1 -> 3 */
-+ matrix[8] = change_matrix[0];
-+ matrix[9] = change_matrix[1];
-+ matrix[10] = change_matrix[2];
-+ matrix[11] = change_matrix[3];
-+
-+ /* from 2 -> 1 */
-+ matrix[0] = change_matrix[4];
-+ matrix[1] = change_matrix[5];
-+ matrix[2] = change_matrix[6];
-+ matrix[3] = change_matrix[7];
-+
-+ /* from 3 -> 2 */
-+ matrix[4] = change_matrix[8];
-+ matrix[5] = change_matrix[9];
-+ matrix[6] = change_matrix[10];
-+ matrix[7] = change_matrix[11];
-+
-+ dc_service_memset(&reg_matrix, 0, sizeof(struct out_csc_color_matrix));
-+
-+ setup_reg_format(matrix, reg_matrix.regval);
-+
-+ program_color_matrix(opp110, &reg_matrix, GRPH_COLOR_MATRIX_SW);
-+}
-+
-+static void prepare_yuv_ideal(
-+ bool b601,
-+ struct fixed31_32 *matrix)
-+{
-+ static const int32_t matrix_1[] = {
-+ 25578516, 50216016, 9752344, 6250000,
-+ -14764391, -28985609, 43750000, 50000000,
-+ 43750000, -36635164, -7114836, 50000000
-+ };
-+
-+ static const int32_t matrix_2[] = {
-+ 18187266, 61183125, 6176484, 6250000,
-+ -10025059, -33724941, 43750000, 50000000,
-+ 43750000, -39738379, -4011621, 50000000
-+ };
-+
-+ const int32_t *matrix_x = b601 ? matrix_1 : matrix_2;
-+
-+ uint32_t i = 0;
-+
-+ do {
-+ matrix[i] = dal_fixed31_32_from_fraction(
-+ matrix_x[i],
-+ 100000000);
-+ ++i;
-+ } while (i != ARRAY_SIZE(matrix_1));
-+}
-+
-+/**
-+ *****************************************************************************
-+ * Function: dal_transform_wide_gamut_set_yuv_adjustment
-+ *
-+ * @param [in] const struct grph_csc_adjustment *adjust
-+ *
-+ * @return
-+ * void
-+ *
-+ * @note calculate and program color adjustments for YUV color spaces
-+ *
-+ * @see
-+ *
-+ *****************************************************************************
-+ */
-+static void set_yuv_adjustment(
-+ struct dce110_opp *opp110,
-+ const struct grph_csc_adjustment *adjust)
-+{
-+ bool b601 = (adjust->c_space == COLOR_SPACE_YPBPR601) ||
-+ (adjust->c_space == COLOR_SPACE_YCBCR601) ||
-+ (adjust->c_space == COLOR_SPACE_YCBCR601_YONLY);
-+ struct out_csc_color_matrix reg_matrix;
-+ struct fixed31_32 matrix[OUTPUT_CSC_MATRIX_SIZE];
-+ struct dc_csc_adjustments adjustments;
-+ struct fixed31_32 ideals[OUTPUT_CSC_MATRIX_SIZE];
-+
-+ prepare_yuv_ideal(b601, ideals);
-+
-+ setup_adjustments(adjust, &adjustments);
-+
-+ if ((adjust->c_space == COLOR_SPACE_YCBCR601_YONLY) ||
-+ (adjust->c_space == COLOR_SPACE_YCBCR709_YONLY))
-+ calculate_adjustments_y_only(
-+ ideals, &adjustments, matrix);
-+ else
-+ calculate_adjustments(
-+ ideals, &adjustments, matrix);
-+
-+ dc_service_memset(&reg_matrix, 0, sizeof(struct out_csc_color_matrix));
-+
-+ setup_reg_format(matrix, reg_matrix.regval);
-+
-+ program_color_matrix(opp110, &reg_matrix, GRPH_COLOR_MATRIX_SW);
-+}
-+
-+static bool configure_graphics_mode(
-+ struct dce110_opp *opp110,
-+ enum csc_color_mode config,
-+ enum graphics_csc_adjust_type csc_adjust_type,
-+ enum color_space color_space)
-+{
-+ struct dc_context *ctx = opp110->base.ctx;
-+ uint32_t addr = DCP_REG(mmOUTPUT_CSC_CONTROL);
-+ uint32_t value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ OUTPUT_CSC_CONTROL,
-+ OUTPUT_CSC_GRPH_MODE);
-+
-+ if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_SW) {
-+ if (config == CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC) {
-+ set_reg_field_value(
-+ value,
-+ 4,
-+ OUTPUT_CSC_CONTROL,
-+ OUTPUT_CSC_GRPH_MODE);
-+ } else {
-+
-+ switch (color_space) {
-+ case COLOR_SPACE_SRGB_FULL_RANGE:
-+ /* by pass */
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ OUTPUT_CSC_CONTROL,
-+ OUTPUT_CSC_GRPH_MODE);
-+ break;
-+ case COLOR_SPACE_SRGB_LIMITED_RANGE:
-+ /* TV RGB */
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ OUTPUT_CSC_CONTROL,
-+ OUTPUT_CSC_GRPH_MODE);
-+ break;
-+ case COLOR_SPACE_YCBCR601:
-+ case COLOR_SPACE_YPBPR601:
-+ case COLOR_SPACE_YCBCR601_YONLY:
-+ /* YCbCr601 */
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ OUTPUT_CSC_CONTROL,
-+ OUTPUT_CSC_GRPH_MODE);
-+ break;
-+ case COLOR_SPACE_YCBCR709:
-+ case COLOR_SPACE_YPBPR709:
-+ case COLOR_SPACE_YCBCR709_YONLY:
-+ /* YCbCr709 */
-+ set_reg_field_value(
-+ value,
-+ 3,
-+ OUTPUT_CSC_CONTROL,
-+ OUTPUT_CSC_GRPH_MODE);
-+ break;
-+ default:
-+ return false;
-+ }
-+ }
-+ } else if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_HW) {
-+ switch (color_space) {
-+ case COLOR_SPACE_SRGB_FULL_RANGE:
-+ /* by pass */
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ OUTPUT_CSC_CONTROL,
-+ OUTPUT_CSC_GRPH_MODE);
-+ break;
-+ case COLOR_SPACE_SRGB_LIMITED_RANGE:
-+ /* TV RGB */
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ OUTPUT_CSC_CONTROL,
-+ OUTPUT_CSC_GRPH_MODE);
-+ break;
-+ case COLOR_SPACE_YCBCR601:
-+ case COLOR_SPACE_YPBPR601:
-+ case COLOR_SPACE_YCBCR601_YONLY:
-+ /* YCbCr601 */
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ OUTPUT_CSC_CONTROL,
-+ OUTPUT_CSC_GRPH_MODE);
-+ break;
-+ case COLOR_SPACE_YCBCR709:
-+ case COLOR_SPACE_YPBPR709:
-+ case COLOR_SPACE_YCBCR709_YONLY:
-+ /* YCbCr709 */
-+ set_reg_field_value(
-+ value,
-+ 3,
-+ OUTPUT_CSC_CONTROL,
-+ OUTPUT_CSC_GRPH_MODE);
-+ break;
-+ default:
-+ return false;
-+ }
-+
-+ } else
-+ /* by pass */
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ OUTPUT_CSC_CONTROL,
-+ OUTPUT_CSC_GRPH_MODE);
-+
-+ addr = DCP_REG(mmOUTPUT_CSC_CONTROL);
-+ dal_write_reg(ctx, addr, value);
-+
-+ return true;
-+}
-+
-+void dce110_opp_set_csc_adjustment(
-+ struct output_pixel_processor *opp,
-+ const struct grph_csc_adjustment *adjust)
-+{
-+ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
-+ enum csc_color_mode config =
-+ CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
-+
-+ /* Apply color adjustments: brightness, saturation, hue, contrast and
-+ * CSC. No need for different color space routine, color space defines
-+ * the ideal values only, but keep original design to allow quick switch
-+ * to the old legacy routines */
-+ switch (adjust->c_space) {
-+ case COLOR_SPACE_SRGB_FULL_RANGE:
-+ set_rgb_adjustment_legacy(opp110, adjust);
-+ break;
-+ case COLOR_SPACE_SRGB_LIMITED_RANGE:
-+ set_rgb_limited_range_adjustment(
-+ opp110, adjust);
-+ break;
-+ case COLOR_SPACE_YCBCR601:
-+ case COLOR_SPACE_YCBCR709:
-+ case COLOR_SPACE_YCBCR601_YONLY:
-+ case COLOR_SPACE_YCBCR709_YONLY:
-+ case COLOR_SPACE_YPBPR601:
-+ case COLOR_SPACE_YPBPR709:
-+ set_yuv_adjustment(opp110, adjust);
-+ break;
-+ default:
-+ set_rgb_adjustment_legacy(opp110, adjust);
-+ break;
-+ }
-+
-+ /* We did everything ,now program DxOUTPUT_CSC_CONTROL */
-+ configure_graphics_mode(opp110, config, adjust->csc_adjust_type,
-+ adjust->c_space);
-+}
-+
-+void dce110_opp_set_csc_default(
-+ struct output_pixel_processor *opp,
-+ const struct default_adjustment *default_adjust)
-+{
-+ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
-+ enum csc_color_mode config =
-+ CSC_COLOR_MODE_GRAPHICS_PREDEFINED;
-+
-+ if (default_adjust->force_hw_default == false) {
-+ const struct out_csc_color_matrix *elm;
-+ /* currently parameter not in use */
-+ enum grph_color_adjust_option option =
-+ GRPH_COLOR_MATRIX_HW_DEFAULT;
-+ uint32_t i;
-+ /*
-+ * HW default false we program locally defined matrix
-+ * HW default true we use predefined hw matrix and we
-+ * do not need to program matrix
-+ * OEM wants the HW default via runtime parameter.
-+ */
-+ option = GRPH_COLOR_MATRIX_SW;
-+
-+ for (i = 0; i < ARRAY_SIZE(global_color_matrix); ++i) {
-+ elm = &global_color_matrix[i];
-+ if (elm->color_space != default_adjust->color_space)
-+ continue;
-+ /* program the matrix with default values from this
-+ * file */
-+ program_color_matrix(opp110, elm, option);
-+ config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
-+ break;
-+ }
-+ }
-+
-+ /* configure the what we programmed :
-+ * 1. Default values from this file
-+ * 2. Use hardware default from ROM_A and we do not need to program
-+ * matrix */
-+
-+ configure_graphics_mode(opp110, config,
-+ default_adjust->csc_adjust_type,
-+ default_adjust->color_space);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_formatter.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_formatter.c
-new file mode 100644
-index 0000000..fdf87bd
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_formatter.c
-@@ -0,0 +1,610 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "dce110_opp.h"
-+
-+#define FMT_REG(reg)\
-+ (reg + opp110->offsets.fmt_offset)
-+
-+/**
-+ * set_truncation
-+ * 1) set truncation depth: 0 for 18 bpp or 1 for 24 bpp
-+ * 2) enable truncation
-+ * 3) HW remove 12bit FMT support for DCE11 power saving reason.
-+ */
-+static void set_truncation(
-+ struct dce110_opp *opp110,
-+ const struct bit_depth_reduction_params *params)
-+{
-+ uint32_t value = 0;
-+ uint32_t addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
-+
-+ /*Disable truncation*/
-+ value = dal_read_reg(opp110->base.ctx, addr);
-+ set_reg_field_value(value, 0,
-+ FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN);
-+ set_reg_field_value(value, 0,
-+ FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_DEPTH);
-+ set_reg_field_value(value, 0,
-+ FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_MODE);
-+
-+ dal_write_reg(opp110->base.ctx, addr, value);
-+
-+ /* no 10bpc trunc on DCE11*/
-+ if (params->flags.TRUNCATE_ENABLED == 0 ||
-+ params->flags.TRUNCATE_DEPTH == 2)
-+ return;
-+
-+ /*Set truncation depth and Enable truncation*/
-+ set_reg_field_value(value, 1,
-+ FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_EN);
-+ set_reg_field_value(value, params->flags.TRUNCATE_MODE,
-+ FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_MODE);
-+ set_reg_field_value(value, params->flags.TRUNCATE_DEPTH,
-+ FMT_BIT_DEPTH_CONTROL, FMT_TRUNCATE_DEPTH);
-+
-+ dal_write_reg(opp110->base.ctx, addr, value);
-+
-+}
-+
-+/**
-+ * set_spatial_dither
-+ * 1) set spatial dithering mode: pattern of seed
-+ * 2) set spatical dithering depth: 0 for 18bpp or 1 for 24bpp
-+ * 3) set random seed
-+ * 4) set random mode
-+ * lfsr is reset every frame or not reset
-+ * RGB dithering method
-+ * 0: RGB data are all dithered with x^28+x^3+1
-+ * 1: R data is dithered with x^28+x^3+1
-+ * G data is dithered with x^28+X^9+1
-+ * B data is dithered with x^28+x^13+1
-+ * enable high pass filter or not
-+ * 5) enable spatical dithering
-+ */
-+static void set_spatial_dither(
-+ struct dce110_opp *opp110,
-+ const struct bit_depth_reduction_params *params)
-+{
-+ uint32_t addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
-+ uint32_t depth_cntl_value = 0;
-+ uint32_t fmt_cntl_value = 0;
-+ uint32_t dither_r_value = 0;
-+ uint32_t dither_g_value = 0;
-+ uint32_t dither_b_value = 0;
-+
-+ /*Disable spatial (random) dithering*/
-+ depth_cntl_value = dal_read_reg(opp110->base.ctx, addr);
-+ set_reg_field_value(depth_cntl_value, 0,
-+ FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_EN);
-+ set_reg_field_value(depth_cntl_value, 0,
-+ FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_MODE);
-+ set_reg_field_value(depth_cntl_value, 0,
-+ FMT_BIT_DEPTH_CONTROL, FMT_SPATIAL_DITHER_DEPTH);
-+ set_reg_field_value(depth_cntl_value, 0,
-+ FMT_BIT_DEPTH_CONTROL, FMT_TEMPORAL_DITHER_EN);
-+ set_reg_field_value(depth_cntl_value, 0,
-+ FMT_BIT_DEPTH_CONTROL, FMT_HIGHPASS_RANDOM_ENABLE);
-+ set_reg_field_value(depth_cntl_value, 0,
-+ FMT_BIT_DEPTH_CONTROL, FMT_FRAME_RANDOM_ENABLE);
-+ set_reg_field_value(depth_cntl_value, 0,
-+ FMT_BIT_DEPTH_CONTROL, FMT_RGB_RANDOM_ENABLE);
-+
-+ dal_write_reg(opp110->base.ctx, addr, depth_cntl_value);
-+
-+ /* no 10bpc on DCE11*/
-+ if (params->flags.SPATIAL_DITHER_ENABLED == 0 ||
-+ params->flags.SPATIAL_DITHER_DEPTH == 2)
-+ return;
-+
-+ addr = FMT_REG(mmFMT_CONTROL);
-+ fmt_cntl_value = dal_read_reg(opp110->base.ctx, addr);
-+ /* only use FRAME_COUNTER_MAX if frameRandom == 1*/
-+ if (params->flags.FRAME_RANDOM == 1) {
-+ if (params->flags.SPATIAL_DITHER_DEPTH == 0 ||
-+ params->flags.SPATIAL_DITHER_DEPTH == 1) {
-+ set_reg_field_value(fmt_cntl_value, 15,
-+ FMT_CONTROL,
-+ FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX);
-+ set_reg_field_value(fmt_cntl_value, 2,
-+ FMT_CONTROL,
-+ FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP);
-+ } else if (params->flags.SPATIAL_DITHER_DEPTH == 2) {
-+ set_reg_field_value(fmt_cntl_value, 3,
-+ FMT_CONTROL,
-+ FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX);
-+ set_reg_field_value(fmt_cntl_value, 1,
-+ FMT_CONTROL,
-+ FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP);
-+ } else
-+ return;
-+ } else {
-+ set_reg_field_value(fmt_cntl_value, 0,
-+ FMT_CONTROL,
-+ FMT_SPATIAL_DITHER_FRAME_COUNTER_MAX);
-+ set_reg_field_value(fmt_cntl_value, 0,
-+ FMT_CONTROL,
-+ FMT_SPATIAL_DITHER_FRAME_COUNTER_BIT_SWAP);
-+ }
-+
-+ dal_write_reg(opp110->base.ctx, addr, fmt_cntl_value);
-+
-+ /*Set seed for random values for
-+ * spatial dithering for R,G,B channels*/
-+ addr = FMT_REG(mmFMT_DITHER_RAND_R_SEED);
-+ set_reg_field_value(dither_r_value, params->r_seed_value,
-+ FMT_DITHER_RAND_R_SEED,
-+ FMT_RAND_R_SEED);
-+ dal_write_reg(opp110->base.ctx, addr, dither_r_value);
-+
-+ addr = FMT_REG(mmFMT_DITHER_RAND_G_SEED);
-+ set_reg_field_value(dither_g_value,
-+ params->g_seed_value,
-+ FMT_DITHER_RAND_G_SEED,
-+ FMT_RAND_G_SEED);
-+ dal_write_reg(opp110->base.ctx, addr, dither_g_value);
-+
-+ addr = FMT_REG(mmFMT_DITHER_RAND_B_SEED);
-+ set_reg_field_value(dither_b_value, params->b_seed_value,
-+ FMT_DITHER_RAND_B_SEED,
-+ FMT_RAND_B_SEED);
-+ dal_write_reg(opp110->base.ctx, addr, dither_b_value);
-+
-+ /* FMT_OFFSET_R_Cr 31:16 0x0 Setting the zero
-+ * offset for the R/Cr channel, lower 4LSB
-+ * is forced to zeros. Typically set to 0
-+ * RGB and 0x80000 YCbCr.
-+ */
-+ /* FMT_OFFSET_G_Y 31:16 0x0 Setting the zero
-+ * offset for the G/Y channel, lower 4LSB is
-+ * forced to zeros. Typically set to 0 RGB
-+ * and 0x80000 YCbCr.
-+ */
-+ /* FMT_OFFSET_B_Cb 31:16 0x0 Setting the zero
-+ * offset for the B/Cb channel, lower 4LSB is
-+ * forced to zeros. Typically set to 0 RGB and
-+ * 0x80000 YCbCr.
-+ */
-+
-+ /*Set spatial dithering bit depth*/
-+ set_reg_field_value(depth_cntl_value,
-+ params->flags.SPATIAL_DITHER_DEPTH,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_SPATIAL_DITHER_DEPTH);
-+
-+ /* Set spatial dithering mode
-+ * (default is Seed patterrn AAAA...)
-+ */
-+ set_reg_field_value(depth_cntl_value,
-+ params->flags.SPATIAL_DITHER_MODE,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_SPATIAL_DITHER_MODE);
-+
-+ /*Reset only at startup*/
-+ set_reg_field_value(depth_cntl_value,
-+ params->flags.FRAME_RANDOM,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_RGB_RANDOM_ENABLE);
-+
-+ /*Set RGB data dithered with x^28+x^3+1*/
-+ set_reg_field_value(depth_cntl_value,
-+ params->flags.RGB_RANDOM,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_RGB_RANDOM_ENABLE);
-+
-+ /*Disable High pass filter*/
-+ set_reg_field_value(depth_cntl_value,
-+ params->flags.HIGHPASS_RANDOM,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_HIGHPASS_RANDOM_ENABLE);
-+
-+ /*Enable spatial dithering*/
-+ set_reg_field_value(depth_cntl_value,
-+ 1,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_SPATIAL_DITHER_EN);
-+
-+ addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
-+ dal_write_reg(opp110->base.ctx, addr, depth_cntl_value);
-+
-+}
-+
-+/**
-+ * SetTemporalDither (Frame Modulation)
-+ * 1) set temporal dither depth
-+ * 2) select pattern: from hard-coded pattern or programmable pattern
-+ * 3) select optimized strips for BGR or RGB LCD sub-pixel
-+ * 4) set s matrix
-+ * 5) set t matrix
-+ * 6) set grey level for 0.25, 0.5, 0.75
-+ * 7) enable temporal dithering
-+ */
-+static void set_temporal_dither(
-+ struct dce110_opp *opp110,
-+ const struct bit_depth_reduction_params *params)
-+{
-+ uint32_t addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
-+ uint32_t value;
-+
-+ /*Disable temporal (frame modulation) dithering first*/
-+ value = dal_read_reg(opp110->base.ctx, addr);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_TEMPORAL_DITHER_EN);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_TEMPORAL_DITHER_RESET);
-+ set_reg_field_value(value,
-+ 0,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_TEMPORAL_DITHER_OFFSET);
-+ set_reg_field_value(value,
-+ 0,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_TEMPORAL_DITHER_DEPTH);
-+ set_reg_field_value(value,
-+ 0,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_TEMPORAL_LEVEL);
-+ set_reg_field_value(value,
-+ 0,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_25FRC_SEL);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_50FRC_SEL);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_75FRC_SEL);
-+
-+ dal_write_reg(opp110->base.ctx, addr, value);
-+
-+ /* no 10bpc dither on DCE11*/
-+ if (params->flags.FRAME_MODULATION_ENABLED == 0 ||
-+ params->flags.FRAME_MODULATION_DEPTH == 2)
-+ return;
-+
-+ /* Set temporal dithering depth*/
-+ set_reg_field_value(value,
-+ params->flags.FRAME_MODULATION_DEPTH,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_TEMPORAL_DITHER_DEPTH);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_TEMPORAL_DITHER_RESET);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_TEMPORAL_DITHER_OFFSET);
-+
-+ /*Select legacy pattern based on FRC and Temporal level*/
-+ addr = FMT_REG(mmFMT_TEMPORAL_DITHER_PATTERN_CONTROL);
-+ dal_write_reg(opp110->base.ctx, addr, 0);
-+ /*Set s matrix*/
-+ addr = FMT_REG(
-+ mmFMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX);
-+ dal_write_reg(opp110->base.ctx, addr, 0);
-+ /*Set t matrix*/
-+ addr = FMT_REG(
-+ mmFMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX);
-+ dal_write_reg(opp110->base.ctx, addr, 0);
-+
-+ /*Select patterns for 0.25, 0.5 and 0.75 grey level*/
-+ set_reg_field_value(value,
-+ params->flags.TEMPORAL_LEVEL,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_TEMPORAL_LEVEL);
-+
-+ set_reg_field_value(value,
-+ params->flags.FRC25,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_25FRC_SEL);
-+
-+ set_reg_field_value(value,
-+ params->flags.FRC50,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_50FRC_SEL);
-+
-+ set_reg_field_value(value,
-+ params->flags.FRC75,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_75FRC_SEL);
-+
-+ /*Enable bit reduction by temporal (frame modulation) dithering*/
-+ set_reg_field_value(value,
-+ 1,
-+ FMT_BIT_DEPTH_CONTROL,
-+ FMT_TEMPORAL_DITHER_EN);
-+
-+ addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
-+ dal_write_reg(opp110->base.ctx, addr, value);
-+
-+}
-+
-+/**
-+ * Set Clamping
-+ * 1) Set clamping format based on bpc - 0 for 6bpc (No clamping)
-+ * 1 for 8 bpc
-+ * 2 for 10 bpc
-+ * 3 for 12 bpc
-+ * 7 for programable
-+ * 2) Enable clamp if Limited range requested
-+ */
-+static void set_clamping(
-+ struct dce110_opp *opp110,
-+ const struct clamping_and_pixel_encoding_params *params)
-+{
-+ uint32_t clamp_cntl_value = 0;
-+ uint32_t red_clamp_value = 0;
-+ uint32_t green_clamp_value = 0;
-+ uint32_t blue_clamp_value = 0;
-+ uint32_t addr = FMT_REG(mmFMT_CLAMP_CNTL);
-+
-+ clamp_cntl_value = dal_read_reg(opp110->base.ctx, addr);
-+
-+ set_reg_field_value(clamp_cntl_value,
-+ 0,
-+ FMT_CLAMP_CNTL,
-+ FMT_CLAMP_DATA_EN);
-+
-+ set_reg_field_value(clamp_cntl_value,
-+ 0,
-+ FMT_CLAMP_CNTL,
-+ FMT_CLAMP_COLOR_FORMAT);
-+
-+ switch (params->clamping_level) {
-+ case CLAMPING_FULL_RANGE:
-+ break;
-+
-+ case CLAMPING_LIMITED_RANGE_8BPC:
-+ set_reg_field_value(clamp_cntl_value,
-+ 1,
-+ FMT_CLAMP_CNTL,
-+ FMT_CLAMP_DATA_EN);
-+
-+ set_reg_field_value(clamp_cntl_value,
-+ 1,
-+ FMT_CLAMP_CNTL,
-+ FMT_CLAMP_COLOR_FORMAT);
-+
-+ break;
-+
-+ case CLAMPING_LIMITED_RANGE_10BPC:
-+ set_reg_field_value(clamp_cntl_value,
-+ 1,
-+ FMT_CLAMP_CNTL,
-+ FMT_CLAMP_DATA_EN);
-+
-+ set_reg_field_value(clamp_cntl_value,
-+ 2,
-+ FMT_CLAMP_CNTL,
-+ FMT_CLAMP_COLOR_FORMAT);
-+
-+ break;
-+ case CLAMPING_LIMITED_RANGE_12BPC:
-+ set_reg_field_value(clamp_cntl_value,
-+ 1,
-+ FMT_CLAMP_CNTL,
-+ FMT_CLAMP_DATA_EN);
-+
-+ set_reg_field_value(clamp_cntl_value,
-+ 3,
-+ FMT_CLAMP_CNTL,
-+ FMT_CLAMP_COLOR_FORMAT);
-+
-+ break;
-+ case CLAMPING_LIMITED_RANGE_PROGRAMMABLE:
-+ set_reg_field_value(clamp_cntl_value,
-+ 1,
-+ FMT_CLAMP_CNTL,
-+ FMT_CLAMP_DATA_EN);
-+
-+ set_reg_field_value(clamp_cntl_value,
-+ 7,
-+ FMT_CLAMP_CNTL,
-+ FMT_CLAMP_COLOR_FORMAT);
-+
-+ /*set the defaults*/
-+ set_reg_field_value(red_clamp_value,
-+ 0x10,
-+ FMT_CLAMP_COMPONENT_R,
-+ FMT_CLAMP_LOWER_R);
-+
-+ set_reg_field_value(red_clamp_value,
-+ 0xFEF,
-+ FMT_CLAMP_COMPONENT_R,
-+ FMT_CLAMP_UPPER_R);
-+
-+ addr = FMT_REG(mmFMT_CLAMP_COMPONENT_R);
-+ dal_write_reg(opp110->base.ctx, addr, red_clamp_value);
-+
-+ set_reg_field_value(green_clamp_value,
-+ 0x10,
-+ FMT_CLAMP_COMPONENT_G,
-+ FMT_CLAMP_LOWER_G);
-+
-+ set_reg_field_value(green_clamp_value,
-+ 0xFEF,
-+ FMT_CLAMP_COMPONENT_G,
-+ FMT_CLAMP_UPPER_G);
-+
-+ addr = FMT_REG(mmFMT_CLAMP_COMPONENT_G);
-+ dal_write_reg(opp110->base.ctx, addr, green_clamp_value);
-+
-+ set_reg_field_value(blue_clamp_value,
-+ 0x10,
-+ FMT_CLAMP_COMPONENT_B,
-+ FMT_CLAMP_LOWER_B);
-+
-+ set_reg_field_value(blue_clamp_value,
-+ 0xFEF,
-+ FMT_CLAMP_COMPONENT_B,
-+ FMT_CLAMP_UPPER_B);
-+
-+ addr = FMT_REG(mmFMT_CLAMP_COMPONENT_B);
-+ dal_write_reg(opp110->base.ctx, addr, blue_clamp_value);
-+
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ addr = FMT_REG(mmFMT_CLAMP_CNTL);
-+ /*Set clamp control*/
-+ dal_write_reg(opp110->base.ctx, addr, clamp_cntl_value);
-+
-+}
-+
-+/**
-+ * set_pixel_encoding
-+ *
-+ * Set Pixel Encoding
-+ * 0: RGB 4:4:4 or YCbCr 4:4:4 or YOnly
-+ * 1: YCbCr 4:2:2
-+ */
-+static void set_pixel_encoding(
-+ struct dce110_opp *opp110,
-+ const struct clamping_and_pixel_encoding_params *params)
-+{
-+ uint32_t fmt_cntl_value;
-+ uint32_t addr = FMT_REG(mmFMT_CONTROL);
-+
-+ /*RGB 4:4:4 or YCbCr 4:4:4 - 0; YCbCr 4:2:2 -1.*/
-+ fmt_cntl_value = dal_read_reg(opp110->base.ctx, addr);
-+
-+ set_reg_field_value(fmt_cntl_value,
-+ 0,
-+ FMT_CONTROL,
-+ FMT_PIXEL_ENCODING);
-+
-+ if (params->pixel_encoding == PIXEL_ENCODING_YCBCR422) {
-+ set_reg_field_value(fmt_cntl_value,
-+ 1,
-+ FMT_CONTROL,
-+ FMT_PIXEL_ENCODING);
-+
-+ /*00 - Pixels drop mode ,01 - Pixels average mode*/
-+ set_reg_field_value(fmt_cntl_value,
-+ 0,
-+ FMT_CONTROL,
-+ FMT_SUBSAMPLING_MODE);
-+
-+ /*00 - Cb before Cr ,01 - Cr before Cb*/
-+ set_reg_field_value(fmt_cntl_value,
-+ 0,
-+ FMT_CONTROL,
-+ FMT_SUBSAMPLING_ORDER);
-+ }
-+ dal_write_reg(opp110->base.ctx, addr, fmt_cntl_value);
-+
-+}
-+
-+void dce110_opp_program_bit_depth_reduction(
-+ struct output_pixel_processor *opp,
-+ const struct bit_depth_reduction_params *params)
-+{
-+ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
-+
-+ set_truncation(opp110, params);
-+ set_spatial_dither(opp110, params);
-+ set_temporal_dither(opp110, params);
-+}
-+
-+void dce110_opp_program_clamping_and_pixel_encoding(
-+ struct output_pixel_processor *opp,
-+ const struct clamping_and_pixel_encoding_params *params)
-+{
-+ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
-+
-+ set_clamping(opp110, params);
-+ set_pixel_encoding(opp110, params);
-+}
-+
-+void dce110_opp_set_dyn_expansion(
-+ struct output_pixel_processor *opp,
-+ enum color_space color_sp,
-+ enum dc_color_depth color_dpth,
-+ enum signal_type signal)
-+{
-+ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
-+ uint32_t value;
-+ bool enable_dyn_exp = false;
-+ uint32_t addr = FMT_REG(mmFMT_DYNAMIC_EXP_CNTL);
-+
-+ value = dal_read_reg(opp->ctx, addr);
-+
-+ set_reg_field_value(value, 0,
-+ FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN);
-+ set_reg_field_value(value, 0,
-+ FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE);
-+
-+ /* From HW programming guide:
-+ FMT_DYNAMIC_EXP_EN = 0 for limited RGB or YCbCr output
-+ FMT_DYNAMIC_EXP_EN = 1 for RGB full range only*/
-+ if (color_sp == COLOR_SPACE_SRGB_FULL_RANGE)
-+ enable_dyn_exp = true;
-+
-+ /*00 - 10-bit -> 12-bit dynamic expansion*/
-+ /*01 - 8-bit -> 12-bit dynamic expansion*/
-+ if (signal == SIGNAL_TYPE_HDMI_TYPE_A) {
-+ switch (color_dpth) {
-+ case COLOR_DEPTH_888:
-+ set_reg_field_value(value, enable_dyn_exp ? 1:0,
-+ FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN);
-+ set_reg_field_value(value, 1,
-+ FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE);
-+ break;
-+ case COLOR_DEPTH_101010:
-+ set_reg_field_value(value, enable_dyn_exp ? 1:0,
-+ FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_EN);
-+ set_reg_field_value(value, 0,
-+ FMT_DYNAMIC_EXP_CNTL, FMT_DYNAMIC_EXP_MODE);
-+ break;
-+ case COLOR_DEPTH_121212:
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ dal_write_reg(opp->ctx, addr, value);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_regamma.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_regamma.c
-new file mode 100644
-index 0000000..4cba172
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_regamma.c
-@@ -0,0 +1,2473 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/* include DCE11 register header files */
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "dce110_opp.h"
-+
-+#define DCP_REG(reg)\
-+ (reg + opp110->offsets.dcp_offset)
-+
-+#define DCFE_REG(reg)\
-+ (reg + opp110->offsets.dcfe_offset)
-+
-+enum {
-+ MAX_PWL_ENTRY = 128,
-+ MAX_REGIONS_NUMBER = 16
-+
-+};
-+
-+struct curve_config {
-+ uint32_t offset;
-+ int8_t segments[MAX_REGIONS_NUMBER];
-+ int8_t begin;
-+};
-+
-+/* BASE */
-+static bool find_software_points(
-+ struct dce110_opp *opp110,
-+ struct fixed31_32 hw_point,
-+ enum channel_name channel,
-+ uint32_t *index_to_start,
-+ uint32_t *index_left,
-+ uint32_t *index_right,
-+ enum hw_point_position *pos)
-+{
-+ const uint32_t max_number =
-+ RGB_256X3X16 + opp110->regamma.extra_points;
-+
-+ struct fixed31_32 left, right;
-+
-+ uint32_t i = *index_to_start;
-+
-+ while (i < max_number) {
-+ if (channel == CHANNEL_NAME_RED) {
-+ left = opp110->
-+ regamma.axis_x_256[i].r;
-+
-+ if (i < max_number - 1)
-+ right = opp110->
-+ regamma.axis_x_256[i + 1].r;
-+ else
-+ right = opp110->
-+ regamma.axis_x_256[max_number - 1].r;
-+ } else if (channel == CHANNEL_NAME_GREEN) {
-+ left = opp110->regamma.axis_x_256[i].g;
-+
-+ if (i < max_number - 1)
-+ right = opp110->
-+ regamma.axis_x_256[i + 1].g;
-+ else
-+ right = opp110->
-+ regamma.axis_x_256[max_number - 1].g;
-+ } else {
-+ left = opp110->regamma.axis_x_256[i].b;
-+
-+ if (i < max_number - 1)
-+ right = opp110->
-+ regamma.axis_x_256[i + 1].b;
-+ else
-+ right = opp110->
-+ regamma.axis_x_256[max_number - 1].b;
-+ }
-+
-+ if (dal_fixed31_32_le(left, hw_point) &&
-+ dal_fixed31_32_le(hw_point, right)) {
-+ *index_to_start = i;
-+ *index_left = i;
-+
-+ if (i < max_number - 1)
-+ *index_right = i + 1;
-+ else
-+ *index_right = max_number - 1;
-+
-+ *pos = HW_POINT_POSITION_MIDDLE;
-+
-+ return true;
-+ } else if ((i == *index_to_start) &&
-+ dal_fixed31_32_le(hw_point, left)) {
-+ *index_to_start = i;
-+ *index_left = i;
-+ *index_right = i;
-+
-+ *pos = HW_POINT_POSITION_LEFT;
-+
-+ return true;
-+ } else if ((i == max_number - 1) &&
-+ dal_fixed31_32_le(right, hw_point)) {
-+ *index_to_start = i;
-+ *index_left = i;
-+ *index_right = i;
-+
-+ *pos = HW_POINT_POSITION_RIGHT;
-+
-+ return true;
-+ }
-+
-+ ++i;
-+ }
-+
-+ return false;
-+}
-+
-+static bool find_software_points_dx(
-+ struct dce110_opp *opp110,
-+ struct fixed31_32 hw_point,
-+ enum channel_name channel,
-+ uint32_t *index_to_start,
-+ uint32_t *index_left,
-+ uint32_t *index_right,
-+ enum hw_point_position *pos)
-+{
-+ const uint32_t max_number = DX_GAMMA_RAMP_MAX +
-+ opp110->regamma.extra_points;
-+
-+ struct fixed31_32 left, right;
-+
-+ uint32_t i = *index_to_start;
-+
-+ while (i < max_number) {
-+ if (channel == CHANNEL_NAME_RED) {
-+ left = opp110->regamma.axis_x_1025[i].r;
-+
-+ if (i < DX_GAMMA_RAMP_MAX - 1)
-+ right = opp110->
-+ regamma.axis_x_1025[i + 1].r;
-+ else
-+ right = opp110->
-+ regamma.axis_x_1025[DX_GAMMA_RAMP_MAX-1].r;
-+ } else if (channel == CHANNEL_NAME_GREEN) {
-+ left = opp110->regamma.axis_x_1025[i].g;
-+
-+ if (i < DX_GAMMA_RAMP_MAX - 1)
-+ right = opp110->
-+ regamma.axis_x_1025[i + 1].g;
-+ else
-+ right = opp110->
-+ regamma.axis_x_1025[DX_GAMMA_RAMP_MAX-1].g;
-+ } else {
-+ left = opp110->regamma.axis_x_1025[i].b;
-+
-+ if (i < DX_GAMMA_RAMP_MAX - 1)
-+ right = opp110->
-+ regamma.axis_x_1025[i + 1].b;
-+ else
-+ right = opp110->
-+ regamma.axis_x_1025[DX_GAMMA_RAMP_MAX-1].b;
-+ }
-+
-+ if (dal_fixed31_32_le(left, hw_point) &&
-+ dal_fixed31_32_le(hw_point, right)) {
-+ *index_to_start = i;
-+ *index_left = i;
-+
-+ if (i < DX_GAMMA_RAMP_MAX - 1)
-+ *index_right = i + 1;
-+ else
-+ *index_right = DX_GAMMA_RAMP_MAX - 1;
-+
-+ *pos = HW_POINT_POSITION_MIDDLE;
-+
-+ return true;
-+ } else if ((i == *index_to_start) &&
-+ dal_fixed31_32_le(hw_point, left)) {
-+ *index_to_start = i;
-+ *index_left = i;
-+ *index_right = i;
-+
-+ *pos = HW_POINT_POSITION_LEFT;
-+
-+ return true;
-+ } else if ((i == max_number - 1) &&
-+ dal_fixed31_32_le(right, hw_point)) {
-+ *index_to_start = i;
-+ *index_left = i;
-+ *index_right = i;
-+
-+ *pos = HW_POINT_POSITION_RIGHT;
-+
-+ return true;
-+ }
-+
-+ ++i;
-+ }
-+
-+ return false;
-+}
-+
-+static bool build_custom_gamma_mapping_coefficients_worker(
-+ struct dce110_opp *opp110,
-+ struct pixel_gamma_point *coeff,
-+ enum channel_name channel,
-+ uint32_t number_of_points,
-+ enum pixel_format pixel_format)
-+{
-+ uint32_t i = 0;
-+
-+ while (i <= number_of_points) {
-+ struct fixed31_32 coord_x;
-+
-+ uint32_t index_to_start = 0;
-+ uint32_t index_left = 0;
-+ uint32_t index_right = 0;
-+
-+ enum hw_point_position hw_pos;
-+
-+ struct gamma_point *point;
-+
-+ struct fixed31_32 left_pos;
-+ struct fixed31_32 right_pos;
-+
-+ if (pixel_format == PIXEL_FORMAT_FP16)
-+ coord_x = opp110->
-+ regamma.coordinates_x[i].adjusted_x;
-+ else if (channel == CHANNEL_NAME_RED)
-+ coord_x = opp110->
-+ regamma.coordinates_x[i].regamma_y_red;
-+ else if (channel == CHANNEL_NAME_GREEN)
-+ coord_x = opp110->
-+ regamma.coordinates_x[i].regamma_y_green;
-+ else
-+ coord_x = opp110->
-+ regamma.coordinates_x[i].regamma_y_blue;
-+
-+ if (!find_software_points(
-+ opp110, coord_x, channel,
-+ &index_to_start, &index_left, &index_right, &hw_pos)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (index_left >= RGB_256X3X16 +
-+ opp110->regamma.extra_points) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (index_right >= RGB_256X3X16 +
-+ opp110->regamma.extra_points) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (channel == CHANNEL_NAME_RED) {
-+ point = &coeff[i].r;
-+
-+ left_pos = opp110->
-+ regamma.axis_x_256[index_left].r;
-+ right_pos = opp110->
-+ regamma.axis_x_256[index_right].r;
-+ } else if (channel == CHANNEL_NAME_GREEN) {
-+ point = &coeff[i].g;
-+
-+ left_pos = opp110->
-+ regamma.axis_x_256[index_left].g;
-+ right_pos = opp110->
-+ regamma.axis_x_256[index_right].g;
-+ } else {
-+ point = &coeff[i].b;
-+
-+ left_pos = opp110->
-+ regamma.axis_x_256[index_left].b;
-+ right_pos = opp110->
-+ regamma.axis_x_256[index_right].b;
-+ }
-+
-+ if (hw_pos == HW_POINT_POSITION_MIDDLE)
-+ point->coeff = dal_fixed31_32_div(
-+ dal_fixed31_32_sub(
-+ coord_x,
-+ left_pos),
-+ dal_fixed31_32_sub(
-+ right_pos,
-+ left_pos));
-+ else if (hw_pos == HW_POINT_POSITION_LEFT)
-+ point->coeff = opp110->regamma.x_min;
-+ else if (hw_pos == HW_POINT_POSITION_RIGHT)
-+ point->coeff = opp110->regamma.x_max2;
-+ else {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ point->left_index = index_left;
-+ point->right_index = index_right;
-+ point->pos = hw_pos;
-+
-+ ++i;
-+ }
-+
-+ return true;
-+}
-+
-+static inline bool build_custom_gamma_mapping_coefficients(
-+ struct dce110_opp *opp110,
-+ enum channel_name channel,
-+ uint32_t number_of_points,
-+ enum pixel_format pixel_format)
-+{
-+ return build_custom_gamma_mapping_coefficients_worker(
-+ opp110, opp110->regamma.coeff128, channel,
-+ number_of_points, pixel_format);
-+}
-+
-+static inline bool build_oem_custom_gamma_mapping_coefficients(
-+ struct dce110_opp *opp110,
-+ enum channel_name channel,
-+ uint32_t number_of_points,
-+ enum pixel_format pixel_format)
-+{
-+ return build_custom_gamma_mapping_coefficients_worker(
-+ opp110, opp110->regamma.coeff128_oem, channel,
-+ number_of_points, pixel_format);
-+}
-+
-+static bool build_custom_dx_gamma_mapping_coefficients(
-+ struct dce110_opp *opp110,
-+ enum channel_name channel,
-+ uint32_t number_of_points,
-+ enum pixel_format pixel_format)
-+{
-+ uint32_t i = 0;
-+
-+ while (i <= number_of_points) {
-+ struct fixed31_32 coord_x;
-+
-+ uint32_t index_to_start = 0;
-+ uint32_t index_left = 0;
-+ uint32_t index_right = 0;
-+
-+ enum hw_point_position hw_pos;
-+
-+ struct gamma_point *point;
-+
-+ struct fixed31_32 left_pos;
-+ struct fixed31_32 right_pos;
-+
-+ if (pixel_format == PIXEL_FORMAT_FP16)
-+ coord_x = opp110->
-+ regamma.coordinates_x[i].adjusted_x;
-+ else if (channel == CHANNEL_NAME_RED)
-+ coord_x = opp110->
-+ regamma.coordinates_x[i].regamma_y_red;
-+ else if (channel == CHANNEL_NAME_GREEN)
-+ coord_x = opp110->
-+ regamma.coordinates_x[i].regamma_y_green;
-+ else
-+ coord_x = opp110->
-+ regamma.coordinates_x[i].regamma_y_blue;
-+
-+ if (!find_software_points_dx(
-+ opp110, coord_x, channel,
-+ &index_to_start, &index_left, &index_right, &hw_pos)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (index_left >= DX_GAMMA_RAMP_MAX +
-+ opp110->regamma.extra_points) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (index_right >= DX_GAMMA_RAMP_MAX +
-+ opp110->regamma.extra_points) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (channel == CHANNEL_NAME_RED) {
-+ point = &opp110->regamma.coeff128_dx[i].r;
-+
-+ left_pos = opp110->
-+ regamma.axis_x_1025[index_left].r;
-+ right_pos = opp110->
-+ regamma.axis_x_1025[index_right].r;
-+ } else if (channel == CHANNEL_NAME_GREEN) {
-+ point = &opp110->regamma.coeff128_dx[i].g;
-+
-+ left_pos = opp110->
-+ regamma.axis_x_1025[index_left].g;
-+ right_pos = opp110->
-+ regamma.axis_x_1025[index_right].g;
-+ } else {
-+ point = &opp110->regamma.coeff128_dx[i].b;
-+
-+ left_pos = opp110->
-+ regamma.axis_x_1025[index_left].b;
-+ right_pos = opp110->
-+ regamma.axis_x_1025[index_right].b;
-+ }
-+
-+ if (hw_pos == HW_POINT_POSITION_MIDDLE)
-+ point->coeff = dal_fixed31_32_div(
-+ dal_fixed31_32_sub(
-+ coord_x,
-+ left_pos),
-+ dal_fixed31_32_sub(
-+ right_pos,
-+ left_pos));
-+ else if (hw_pos == HW_POINT_POSITION_LEFT)
-+ point->coeff = opp110->regamma.x_min;
-+ else if (hw_pos == HW_POINT_POSITION_RIGHT)
-+ point->coeff = opp110->regamma.x_max2;
-+ else {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ point->left_index = index_left;
-+ point->right_index = index_right;
-+ point->pos = hw_pos;
-+
-+ ++i;
-+ }
-+
-+ return true;
-+}
-+
-+static struct fixed31_32 calculate_mapped_value(
-+ struct dce110_opp *opp110,
-+ struct pwl_float_data *rgb,
-+ const struct pixel_gamma_point *coeff,
-+ enum channel_name channel,
-+ uint32_t max_index)
-+{
-+ const struct gamma_point *point;
-+
-+ struct fixed31_32 result;
-+
-+ if (channel == CHANNEL_NAME_RED)
-+ point = &coeff->r;
-+ else if (channel == CHANNEL_NAME_GREEN)
-+ point = &coeff->g;
-+ else
-+ point = &coeff->b;
-+
-+ if ((point->left_index < 0) || (point->left_index > max_index)) {
-+ BREAK_TO_DEBUGGER();
-+ return dal_fixed31_32_zero;
-+ }
-+
-+ if ((point->right_index < 0) || (point->right_index > max_index)) {
-+ BREAK_TO_DEBUGGER();
-+ return dal_fixed31_32_zero;
-+ }
-+
-+ if (point->pos == HW_POINT_POSITION_MIDDLE)
-+ if (channel == CHANNEL_NAME_RED)
-+ result = dal_fixed31_32_add(
-+ dal_fixed31_32_mul(
-+ point->coeff,
-+ dal_fixed31_32_sub(
-+ rgb[point->right_index].r,
-+ rgb[point->left_index].r)),
-+ rgb[point->left_index].r);
-+ else if (channel == CHANNEL_NAME_GREEN)
-+ result = dal_fixed31_32_add(
-+ dal_fixed31_32_mul(
-+ point->coeff,
-+ dal_fixed31_32_sub(
-+ rgb[point->right_index].g,
-+ rgb[point->left_index].g)),
-+ rgb[point->left_index].g);
-+ else
-+ result = dal_fixed31_32_add(
-+ dal_fixed31_32_mul(
-+ point->coeff,
-+ dal_fixed31_32_sub(
-+ rgb[point->right_index].b,
-+ rgb[point->left_index].b)),
-+ rgb[point->left_index].b);
-+ else if (point->pos == HW_POINT_POSITION_LEFT) {
-+ BREAK_TO_DEBUGGER();
-+ result = opp110->regamma.x_min;
-+ } else {
-+ BREAK_TO_DEBUGGER();
-+ result = opp110->regamma.x_max1;
-+ }
-+
-+ return result;
-+}
-+
-+static inline struct fixed31_32 calculate_regamma_user_mapped_value(
-+ struct dce110_opp *opp110,
-+ const struct pixel_gamma_point *coeff,
-+ enum channel_name channel,
-+ uint32_t max_index)
-+{
-+ return calculate_mapped_value(
-+ opp110, opp110->regamma.rgb_oem,
-+ coeff, channel, max_index);
-+}
-+
-+static inline struct fixed31_32 calculate_user_mapped_value(
-+ struct dce110_opp *opp110,
-+ const struct pixel_gamma_point *coeff,
-+ enum channel_name channel,
-+ uint32_t max_index)
-+{
-+ return calculate_mapped_value(
-+ opp110, opp110->regamma.rgb_user,
-+ coeff, channel, max_index);
-+}
-+
-+static inline struct fixed31_32 calculate_oem_mapped_value(
-+ struct dce110_opp *opp110,
-+ uint32_t index,
-+ enum channel_name channel,
-+ uint32_t max_index)
-+{
-+ return calculate_regamma_user_mapped_value(
-+ opp110, opp110->regamma.coeff128_oem +
-+ index, channel, max_index);
-+}
-+
-+static void scale_oem_gamma(
-+ struct dce110_opp *opp110,
-+ const struct regamma_ramp *regamma_ramp)
-+{
-+ const uint16_t max_driver = 0xFFFF;
-+ const uint16_t max_os = 0xFF00;
-+
-+ uint16_t scale = max_os;
-+
-+ uint32_t i;
-+
-+ struct pwl_float_data *rgb = opp110->regamma.rgb_oem;
-+ struct pwl_float_data *rgb_last = rgb + RGB_256X3X16 - 1;
-+
-+ /* find OEM maximum */
-+
-+ i = 0;
-+
-+ do {
-+ if ((regamma_ramp->gamma[i] > max_os) ||
-+ (regamma_ramp->gamma[i + RGB_256X3X16] > max_os) ||
-+ (regamma_ramp->gamma[i + 2 * RGB_256X3X16] > max_os)) {
-+ scale = max_driver;
-+ break;
-+ }
-+
-+ ++i;
-+ } while (i != RGB_256X3X16);
-+
-+ /* scale */
-+
-+ i = 0;
-+
-+ do {
-+ rgb->r = dal_fixed31_32_div_int(
-+ dal_fixed31_32_from_int(
-+ regamma_ramp->gamma[i]),
-+ scale);
-+ rgb->g = dal_fixed31_32_div_int(
-+ dal_fixed31_32_from_int(
-+ regamma_ramp->gamma[i + RGB_256X3X16]),
-+ scale);
-+ rgb->b = dal_fixed31_32_div_int(
-+ dal_fixed31_32_from_int(
-+ regamma_ramp->gamma[i + 2 * RGB_256X3X16]),
-+ scale);
-+
-+ ++rgb;
-+ ++i;
-+ } while (i != RGB_256X3X16);
-+
-+ /* add 3 extra points, 2 physical plus 1 virtual */
-+
-+ rgb->r = dal_fixed31_32_mul(rgb_last->r,
-+ opp110->regamma.divider1);
-+ rgb->g = dal_fixed31_32_mul(rgb_last->g,
-+ opp110->regamma.divider1);
-+ rgb->b = dal_fixed31_32_mul(rgb_last->b,
-+ opp110->regamma.divider1);
-+
-+ ++rgb;
-+
-+ rgb->r = dal_fixed31_32_mul(rgb_last->r,
-+ opp110->regamma.divider2);
-+ rgb->g = dal_fixed31_32_mul(rgb_last->g,
-+ opp110->regamma.divider2);
-+ rgb->b = dal_fixed31_32_mul(rgb_last->b,
-+ opp110->regamma.divider2);
-+
-+ ++rgb;
-+
-+ rgb->r = dal_fixed31_32_mul(rgb_last->r,
-+ opp110->regamma.divider3);
-+ rgb->g = dal_fixed31_32_mul(rgb_last->g,
-+ opp110->regamma.divider3);
-+ rgb->b = dal_fixed31_32_mul(rgb_last->b,
-+ opp110->regamma.divider3);
-+}
-+
-+static inline void copy_rgb_regamma_to_coordinates_x(
-+ struct dce110_opp *opp110)
-+{
-+ struct hw_x_point *coords = opp110->regamma.coordinates_x;
-+ const struct pwl_float_data_ex *rgb_regamma =
-+ opp110->regamma.rgb_regamma;
-+
-+ uint32_t i = 0;
-+
-+ while (i <= opp110->regamma.hw_points_num) {
-+ coords->regamma_y_red = rgb_regamma->r;
-+ coords->regamma_y_green = rgb_regamma->g;
-+ coords->regamma_y_blue = rgb_regamma->b;
-+
-+ ++coords;
-+ ++rgb_regamma;
-+ ++i;
-+ }
-+}
-+
-+static bool calculate_interpolated_hardware_curve(
-+ struct dce110_opp *opp110,
-+ const struct gamma_ramp *gamma_ramp,
-+ const struct gamma_parameters *params)
-+{
-+ struct pwl_result_data *rgb_resulted =
-+ opp110->regamma.rgb_resulted;
-+
-+ const struct pixel_gamma_point *coeff;
-+ uint32_t max_entries = opp110->regamma.extra_points - 1;
-+
-+ uint32_t i = 0;
-+
-+ if (gamma_ramp->type == GAMMA_RAMP_RBG256X3X16) {
-+ if (!build_custom_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_RED,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!build_custom_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_GREEN,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!build_custom_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_BLUE,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ coeff = opp110->regamma.coeff128;
-+ max_entries += RGB_256X3X16;
-+ } else if (gamma_ramp->type == GAMMA_RAMP_DXGI_1) {
-+ if (!build_custom_dx_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_RED,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!build_custom_dx_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_GREEN,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!build_custom_dx_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_BLUE,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ coeff = opp110->regamma.coeff128_dx;
-+ max_entries += DX_GAMMA_RAMP_MAX;
-+ } else {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ while (i <= opp110->regamma.hw_points_num) {
-+ rgb_resulted->red = calculate_user_mapped_value(
-+ opp110, coeff, CHANNEL_NAME_RED, max_entries);
-+ rgb_resulted->green = calculate_user_mapped_value(
-+ opp110, coeff, CHANNEL_NAME_GREEN, max_entries);
-+ rgb_resulted->blue = calculate_user_mapped_value(
-+ opp110, coeff, CHANNEL_NAME_BLUE, max_entries);
-+
-+ ++coeff;
-+ ++rgb_resulted;
-+ ++i;
-+ }
-+
-+ return true;
-+}
-+
-+static void map_standard_regamma_hw_to_x_user(
-+ struct dce110_opp *opp110,
-+ enum gamma_ramp_type type,
-+ const struct gamma_parameters *params)
-+{
-+ struct pwl_result_data *rgb_resulted =
-+ opp110->regamma.rgb_resulted;
-+ const struct pwl_float_data_ex *rgb_regamma =
-+ opp110->regamma.rgb_regamma;
-+
-+ uint32_t i = 0;
-+
-+ while (i <= opp110->regamma.hw_points_num) {
-+ rgb_resulted->red = rgb_regamma->r;
-+ rgb_resulted->green = rgb_regamma->g;
-+ rgb_resulted->blue = rgb_regamma->b;
-+
-+ ++rgb_resulted;
-+ ++rgb_regamma;
-+ ++i;
-+ }
-+}
-+
-+bool dce110_opp_map_legacy_and_regamma_hw_to_x_user(
-+ struct output_pixel_processor *opp,
-+ const struct gamma_ramp *gamma_ramp,
-+ const struct gamma_parameters *params)
-+{
-+ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
-+
-+ if (params->regamma.features.bits.GAMMA_RAMP_ARRAY ||
-+ params->regamma.features.bits.APPLY_DEGAMMA) {
-+
-+ const uint32_t max_entries =
-+ RGB_256X3X16 + opp110->regamma.extra_points - 1;
-+
-+ const struct pixel_gamma_point *coeff =
-+ opp110->regamma.coeff128;
-+ struct pwl_result_data *rgb_resulted =
-+ opp110->regamma.rgb_resulted;
-+
-+ uint32_t i = 0;
-+
-+ scale_oem_gamma(opp110, &params->regamma.regamma_ramp);
-+
-+ copy_rgb_regamma_to_coordinates_x(opp110);
-+
-+ if (!build_custom_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_RED,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!build_custom_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_GREEN,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!build_custom_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_BLUE,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ while (i <= opp110->regamma.hw_points_num) {
-+ rgb_resulted->red =
-+ calculate_regamma_user_mapped_value(opp110,
-+ coeff,
-+ CHANNEL_NAME_RED, max_entries);
-+ rgb_resulted->green =
-+ calculate_regamma_user_mapped_value(opp110,
-+ coeff,
-+ CHANNEL_NAME_GREEN, max_entries);
-+ rgb_resulted->blue =
-+ calculate_regamma_user_mapped_value(opp110,
-+ coeff,
-+ CHANNEL_NAME_BLUE, max_entries);
-+
-+ ++coeff;
-+ ++rgb_resulted;
-+ ++i;
-+ }
-+ } else
-+ map_standard_regamma_hw_to_x_user(opp110,
-+ gamma_ramp->type,
-+ params);
-+
-+ return true;
-+}
-+
-+static bool map_regamma_hw_to_x_user(
-+ struct dce110_opp *opp110,
-+ const struct gamma_ramp *gamma_ramp,
-+ const struct gamma_parameters *params)
-+{
-+ /* setup to spare calculated ideal regamma values */
-+ if (params->regamma.features.bits.GAMMA_RAMP_ARRAY ||
-+ params->regamma.features.bits.APPLY_DEGAMMA) {
-+
-+ const uint32_t max_entries =
-+ RGB_256X3X16 + opp110->regamma.extra_points - 1;
-+
-+ const struct pixel_gamma_point *coeff =
-+ opp110->regamma.coeff128;
-+ struct hw_x_point *coords =
-+ opp110->regamma.coordinates_x;
-+
-+ uint32_t i = 0;
-+
-+ scale_oem_gamma(opp110, &params->regamma.regamma_ramp);
-+
-+ copy_rgb_regamma_to_coordinates_x(opp110);
-+
-+ if (!build_custom_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_RED,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!build_custom_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_GREEN,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!build_custom_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_BLUE,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ while (i <= opp110->regamma.hw_points_num) {
-+ coords->regamma_y_red =
-+ calculate_regamma_user_mapped_value(opp110,
-+ coeff,
-+ CHANNEL_NAME_RED, max_entries);
-+ coords->regamma_y_green =
-+ calculate_regamma_user_mapped_value(opp110,
-+ coeff,
-+ CHANNEL_NAME_GREEN, max_entries);
-+ coords->regamma_y_blue =
-+ calculate_regamma_user_mapped_value(opp110,
-+ coeff,
-+ CHANNEL_NAME_BLUE, max_entries);
-+
-+ ++coeff;
-+ ++coords;
-+ ++i;
-+ }
-+ } else {
-+ copy_rgb_regamma_to_coordinates_x(opp110);
-+ }
-+
-+ return calculate_interpolated_hardware_curve(opp110, gamma_ramp,
-+ params);
-+}
-+
-+static void build_regamma_coefficients(
-+ const struct regamma_lut *regamma,
-+ bool is_degamma_srgb,
-+ struct gamma_coefficients *coefficients)
-+{
-+ /* sRGB should apply 2.4 */
-+ static const int32_t numerator01[3] = { 31308, 31308, 31308 };
-+ static const int32_t numerator02[3] = { 12920, 12920, 12920 };
-+ static const int32_t numerator03[3] = { 55, 55, 55 };
-+ static const int32_t numerator04[3] = { 55, 55, 55 };
-+ static const int32_t numerator05[3] = { 2400, 2400, 2400 };
-+
-+ /* Non-sRGB should apply 2.2 */
-+ static const int32_t numerator11[3] = { 180000, 180000, 180000 };
-+ static const int32_t numerator12[3] = { 4500, 4500, 4500 };
-+ static const int32_t numerator13[3] = { 99, 99, 99 };
-+ static const int32_t numerator14[3] = { 99, 99, 99 };
-+ static const int32_t numerator15[3] = { 2200, 2200, 2200 };
-+
-+ const int32_t *numerator1;
-+ const int32_t *numerator2;
-+ const int32_t *numerator3;
-+ const int32_t *numerator4;
-+ const int32_t *numerator5;
-+
-+ uint32_t i = 0;
-+
-+ if (!regamma->features.bits.GAMMA_RAMP_ARRAY) {
-+ numerator1 = regamma->gamma_coeff.a0;
-+ numerator2 = regamma->gamma_coeff.a1;
-+ numerator3 = regamma->gamma_coeff.a2;
-+ numerator4 = regamma->gamma_coeff.a3;
-+ numerator5 = regamma->gamma_coeff.gamma;
-+ } else if (is_degamma_srgb) {
-+ numerator1 = numerator01;
-+ numerator2 = numerator02;
-+ numerator3 = numerator03;
-+ numerator4 = numerator04;
-+ numerator5 = numerator05;
-+ } else {
-+ numerator1 = numerator11;
-+ numerator2 = numerator12;
-+ numerator3 = numerator13;
-+ numerator4 = numerator14;
-+ numerator5 = numerator15;
-+ }
-+
-+ do {
-+ coefficients->a0[i] = dal_fixed31_32_from_fraction(
-+ numerator1[i], 10000000);
-+ coefficients->a1[i] = dal_fixed31_32_from_fraction(
-+ numerator2[i], 1000);
-+ coefficients->a2[i] = dal_fixed31_32_from_fraction(
-+ numerator3[i], 1000);
-+ coefficients->a3[i] = dal_fixed31_32_from_fraction(
-+ numerator4[i], 1000);
-+ coefficients->user_gamma[i] = dal_fixed31_32_from_fraction(
-+ numerator5[i], 1000);
-+
-+ ++i;
-+ } while (i != ARRAY_SIZE(regamma->gamma_coeff.a0));
-+}
-+
-+static struct fixed31_32 translate_from_linear_space(
-+ struct fixed31_32 arg,
-+ struct fixed31_32 a0,
-+ struct fixed31_32 a1,
-+ struct fixed31_32 a2,
-+ struct fixed31_32 a3,
-+ struct fixed31_32 gamma)
-+{
-+ const struct fixed31_32 one = dal_fixed31_32_from_int(1);
-+
-+ if (dal_fixed31_32_le(arg, dal_fixed31_32_neg(a0)))
-+ return dal_fixed31_32_sub(
-+ a2,
-+ dal_fixed31_32_mul(
-+ dal_fixed31_32_add(
-+ one,
-+ a3),
-+ dal_fixed31_32_pow(
-+ dal_fixed31_32_neg(arg),
-+ dal_fixed31_32_recip(gamma))));
-+ else if (dal_fixed31_32_le(a0, arg))
-+ return dal_fixed31_32_sub(
-+ dal_fixed31_32_mul(
-+ dal_fixed31_32_add(
-+ one,
-+ a3),
-+ dal_fixed31_32_pow(
-+ arg,
-+ dal_fixed31_32_recip(gamma))),
-+ a2);
-+ else
-+ return dal_fixed31_32_mul(
-+ arg,
-+ a1);
-+}
-+
-+static inline struct fixed31_32 translate_from_linear_space_ex(
-+ struct fixed31_32 arg,
-+ struct gamma_coefficients *coeff,
-+ uint32_t color_index)
-+{
-+ return translate_from_linear_space(
-+ arg,
-+ coeff->a0[color_index],
-+ coeff->a1[color_index],
-+ coeff->a2[color_index],
-+ coeff->a3[color_index],
-+ coeff->user_gamma[color_index]);
-+}
-+
-+static bool build_regamma_curve(
-+ struct dce110_opp *opp110,
-+ const struct gamma_parameters *params)
-+{
-+ struct pwl_float_data_ex *rgb = opp110->regamma.rgb_regamma;
-+
-+ uint32_t i;
-+
-+ if (!params->regamma.features.bits.GAMMA_RAMP_ARRAY &&
-+ params->regamma.features.bits.APPLY_DEGAMMA) {
-+ struct gamma_coefficients coeff;
-+
-+ struct hw_x_point *coord_x =
-+ opp110->regamma.coordinates_x;
-+
-+ build_regamma_coefficients(
-+ &params->regamma,
-+ params->regamma.features.bits.GRAPHICS_DEGAMMA_SRGB,
-+ &coeff);
-+
-+ /* Use opp110->regamma.coordinates_x to retrieve
-+ * coordinates chosen base on given user curve (future task).
-+ * The x values are exponentially distributed and currently
-+ * it is hard-coded, the user curve shape is ignored.
-+ * The future task is to recalculate opp110-
-+ * regamma.coordinates_x based on input/user curve,
-+ * translation from 256/1025 to 128 pwl points.
-+ */
-+
-+ i = 0;
-+
-+ while (i != opp110->regamma.hw_points_num + 1) {
-+ rgb->r = translate_from_linear_space_ex(
-+ coord_x->adjusted_x, &coeff, 0);
-+ rgb->g = translate_from_linear_space_ex(
-+ coord_x->adjusted_x, &coeff, 1);
-+ rgb->b = translate_from_linear_space_ex(
-+ coord_x->adjusted_x, &coeff, 2);
-+
-+ ++coord_x;
-+ ++rgb;
-+ ++i;
-+ }
-+ } else {
-+ const uint32_t max_entries =
-+ RGB_256X3X16 + opp110->regamma.extra_points - 1;
-+
-+ /* interpolate between 256 input points and output 185 points */
-+
-+ scale_oem_gamma(opp110, &params->regamma.regamma_ramp);
-+
-+ if (!build_oem_custom_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_RED,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!build_oem_custom_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_GREEN,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!build_oem_custom_gamma_mapping_coefficients(
-+ opp110, CHANNEL_NAME_BLUE,
-+ opp110->regamma.hw_points_num,
-+ params->surface_pixel_format)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ i = 0;
-+
-+ while (i != opp110->regamma.hw_points_num + 1) {
-+ rgb->r = calculate_oem_mapped_value(
-+ opp110, i, CHANNEL_NAME_RED, max_entries);
-+ rgb->g = calculate_oem_mapped_value(
-+ opp110, i, CHANNEL_NAME_GREEN, max_entries);
-+ rgb->b = calculate_oem_mapped_value(
-+ opp110, i, CHANNEL_NAME_BLUE, max_entries);
-+ ++rgb;
-+ ++i;
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+static void build_new_custom_resulted_curve(
-+ struct dce110_opp *opp110,
-+ const struct gamma_parameters *params)
-+{
-+ struct pwl_result_data *rgb = opp110->regamma.rgb_resulted;
-+ struct pwl_result_data *rgb_plus_1 = rgb + 1;
-+
-+ uint32_t i;
-+
-+ i = 0;
-+
-+ while (i != opp110->regamma.hw_points_num + 1) {
-+ rgb->red = dal_fixed31_32_clamp(
-+ rgb->red, opp110->regamma.x_min,
-+ opp110->regamma.x_max1);
-+ rgb->green = dal_fixed31_32_clamp(
-+ rgb->green, opp110->regamma.x_min,
-+ opp110->regamma.x_max1);
-+ rgb->blue = dal_fixed31_32_clamp(
-+ rgb->blue, opp110->regamma.x_min,
-+ opp110->regamma.x_max1);
-+
-+ ++rgb;
-+ ++i;
-+ }
-+
-+ rgb = opp110->regamma.rgb_resulted;
-+
-+ i = 1;
-+
-+ while (i != opp110->regamma.hw_points_num + 1) {
-+ if (dal_fixed31_32_lt(rgb_plus_1->red, rgb->red))
-+ rgb_plus_1->red = rgb->red;
-+ if (dal_fixed31_32_lt(rgb_plus_1->green, rgb->green))
-+ rgb_plus_1->green = rgb->green;
-+ if (dal_fixed31_32_lt(rgb_plus_1->blue, rgb->blue))
-+ rgb_plus_1->blue = rgb->blue;
-+
-+ rgb->delta_red = dal_fixed31_32_sub(
-+ rgb_plus_1->red,
-+ rgb->red);
-+ rgb->delta_green = dal_fixed31_32_sub(
-+ rgb_plus_1->green,
-+ rgb->green);
-+ rgb->delta_blue = dal_fixed31_32_sub(
-+ rgb_plus_1->blue,
-+ rgb->blue);
-+
-+ ++rgb_plus_1;
-+ ++rgb;
-+ ++i;
-+ }
-+}
-+
-+static bool rebuild_curve_configuration_magic(
-+ struct dce110_opp *opp110)
-+{
-+ const struct fixed31_32 magic_number =
-+ dal_fixed31_32_from_fraction(249, 1000);
-+
-+ struct fixed31_32 y_r;
-+ struct fixed31_32 y_g;
-+ struct fixed31_32 y_b;
-+
-+ struct fixed31_32 y1_min;
-+ struct fixed31_32 y2_max;
-+ struct fixed31_32 y3_max;
-+
-+ y_r = opp110->regamma.rgb_resulted[0].red;
-+ y_g = opp110->regamma.rgb_resulted[0].green;
-+ y_b = opp110->regamma.rgb_resulted[0].blue;
-+
-+ y1_min = dal_fixed31_32_min(y_r, dal_fixed31_32_min(y_g, y_b));
-+
-+ opp110->regamma.arr_points[0].x =
-+ opp110->regamma.coordinates_x[0].adjusted_x;
-+ opp110->regamma.arr_points[0].y = y1_min;
-+ opp110->regamma.arr_points[0].slope = dal_fixed31_32_div(
-+ opp110->regamma.arr_points[0].y,
-+ opp110->regamma.arr_points[0].x);
-+
-+ opp110->regamma.arr_points[1].x = dal_fixed31_32_add(
-+ opp110->regamma.coordinates_x
-+ [opp110->regamma.hw_points_num - 1].adjusted_x,
-+ magic_number);
-+
-+ opp110->regamma.arr_points[2].x =
-+ opp110->regamma.arr_points[1].x;
-+
-+ y_r = opp110->regamma.rgb_resulted
-+ [opp110->regamma.hw_points_num - 1].red;
-+ y_g = opp110->regamma.rgb_resulted
-+ [opp110->regamma.hw_points_num - 1].green;
-+ y_b = opp110->regamma.rgb_resulted
-+ [opp110->regamma.hw_points_num - 1].blue;
-+
-+ y2_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b));
-+
-+ opp110->regamma.arr_points[1].y = y2_max;
-+
-+ y_r = opp110->regamma.rgb_resulted
-+ [opp110->regamma.hw_points_num].red;
-+ y_g = opp110->regamma.rgb_resulted
-+ [opp110->regamma.hw_points_num].green;
-+ y_b = opp110->regamma.rgb_resulted
-+ [opp110->regamma.hw_points_num].blue;
-+
-+ y3_max = dal_fixed31_32_max(y_r, dal_fixed31_32_max(y_g, y_b));
-+
-+ opp110->regamma.arr_points[2].y = y3_max;
-+
-+ opp110->regamma.arr_points[2].slope = dal_fixed31_32_one;
-+
-+ return true;
-+}
-+
-+static bool build_custom_float(
-+ struct fixed31_32 value,
-+ const struct custom_float_format *format,
-+ bool *negative,
-+ uint32_t *mantissa,
-+ uint32_t *exponenta)
-+{
-+ uint32_t exp_offset = (1 << (format->exponenta_bits - 1)) - 1;
-+
-+ const struct fixed31_32 mantissa_constant_plus_max_fraction =
-+ dal_fixed31_32_from_fraction(
-+ (1LL << (format->mantissa_bits + 1)) - 1,
-+ 1LL << format->mantissa_bits);
-+
-+ struct fixed31_32 mantiss;
-+
-+ if (dal_fixed31_32_eq(
-+ value,
-+ dal_fixed31_32_zero)) {
-+ *negative = false;
-+ *mantissa = 0;
-+ *exponenta = 0;
-+ return true;
-+ }
-+
-+ if (dal_fixed31_32_lt(
-+ value,
-+ dal_fixed31_32_zero)) {
-+ *negative = format->sign;
-+ value = dal_fixed31_32_neg(value);
-+ } else {
-+ *negative = false;
-+ }
-+
-+ if (dal_fixed31_32_lt(
-+ value,
-+ dal_fixed31_32_one)) {
-+ uint32_t i = 1;
-+
-+ do {
-+ value = dal_fixed31_32_shl(value, 1);
-+ ++i;
-+ } while (dal_fixed31_32_lt(
-+ value,
-+ dal_fixed31_32_one));
-+
-+ --i;
-+
-+ if (exp_offset <= i) {
-+ *mantissa = 0;
-+ *exponenta = 0;
-+ return true;
-+ }
-+
-+ *exponenta = exp_offset - i;
-+ } else if (dal_fixed31_32_le(
-+ mantissa_constant_plus_max_fraction,
-+ value)) {
-+ uint32_t i = 1;
-+
-+ do {
-+ value = dal_fixed31_32_shr(value, 1);
-+ ++i;
-+ } while (dal_fixed31_32_lt(
-+ mantissa_constant_plus_max_fraction,
-+ value));
-+
-+ *exponenta = exp_offset + i - 1;
-+ } else {
-+ *exponenta = exp_offset;
-+ }
-+
-+ mantiss = dal_fixed31_32_sub(
-+ value,
-+ dal_fixed31_32_one);
-+
-+ if (dal_fixed31_32_lt(
-+ mantiss,
-+ dal_fixed31_32_zero) ||
-+ dal_fixed31_32_lt(
-+ dal_fixed31_32_one,
-+ mantiss))
-+ mantiss = dal_fixed31_32_zero;
-+ else
-+ mantiss = dal_fixed31_32_shl(
-+ mantiss,
-+ format->mantissa_bits);
-+
-+ *mantissa = dal_fixed31_32_floor(mantiss);
-+
-+ return true;
-+}
-+
-+static bool setup_custom_float(
-+ const struct custom_float_format *format,
-+ bool negative,
-+ uint32_t mantissa,
-+ uint32_t exponenta,
-+ uint32_t *result)
-+{
-+ uint32_t i = 0;
-+ uint32_t j = 0;
-+
-+ uint32_t value = 0;
-+
-+ /* verification code:
-+ * once calculation is ok we can remove it */
-+
-+ const uint32_t mantissa_mask =
-+ (1 << (format->mantissa_bits + 1)) - 1;
-+
-+ const uint32_t exponenta_mask =
-+ (1 << (format->exponenta_bits + 1)) - 1;
-+
-+ if (mantissa & ~mantissa_mask) {
-+ BREAK_TO_DEBUGGER();
-+ mantissa = mantissa_mask;
-+ }
-+
-+ if (exponenta & ~exponenta_mask) {
-+ BREAK_TO_DEBUGGER();
-+ exponenta = exponenta_mask;
-+ }
-+
-+ /* end of verification code */
-+
-+ while (i < format->mantissa_bits) {
-+ uint32_t mask = 1 << i;
-+
-+ if (mantissa & mask)
-+ value |= mask;
-+
-+ ++i;
-+ }
-+
-+ while (j < format->exponenta_bits) {
-+ uint32_t mask = 1 << j;
-+
-+ if (exponenta & mask)
-+ value |= mask << i;
-+
-+ ++j;
-+ }
-+
-+ if (negative && format->sign)
-+ value |= 1 << (i + j);
-+
-+ *result = value;
-+
-+ return true;
-+}
-+
-+static bool convert_to_custom_float_format(
-+ struct fixed31_32 value,
-+ const struct custom_float_format *format,
-+ uint32_t *result)
-+{
-+ uint32_t mantissa;
-+ uint32_t exponenta;
-+ bool negative;
-+
-+ return build_custom_float(
-+ value, format, &negative, &mantissa, &exponenta) &&
-+ setup_custom_float(
-+ format, negative, mantissa, exponenta, result);
-+}
-+
-+static bool convert_to_custom_float_format_ex(
-+ struct fixed31_32 value,
-+ const struct custom_float_format *format,
-+ struct custom_float_value *result)
-+{
-+ return build_custom_float(
-+ value, format,
-+ &result->negative, &result->mantissa, &result->exponenta) &&
-+ setup_custom_float(
-+ format, result->negative, result->mantissa, result->exponenta,
-+ &result->value);
-+}
-+
-+static bool convert_to_custom_float(
-+ struct dce110_opp *opp110)
-+{
-+ struct custom_float_format fmt;
-+
-+ struct pwl_result_data *rgb = opp110->regamma.rgb_resulted;
-+
-+ uint32_t i = 0;
-+
-+ fmt.exponenta_bits = 6;
-+ fmt.mantissa_bits = 12;
-+ fmt.sign = true;
-+
-+ if (!convert_to_custom_float_format(
-+ opp110->regamma.arr_points[0].x,
-+ &fmt,
-+ &opp110->regamma.arr_points[0].custom_float_x)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!convert_to_custom_float_format(
-+ opp110->regamma.arr_points[0].offset,
-+ &fmt,
-+ &opp110->regamma.arr_points[0].custom_float_offset)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!convert_to_custom_float_format(
-+ opp110->regamma.arr_points[0].slope,
-+ &fmt,
-+ &opp110->regamma.arr_points[0].custom_float_slope)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ fmt.mantissa_bits = 10;
-+ fmt.sign = false;
-+
-+ if (!convert_to_custom_float_format(
-+ opp110->regamma.arr_points[1].x,
-+ &fmt,
-+ &opp110->regamma.arr_points[1].custom_float_x)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!convert_to_custom_float_format(
-+ opp110->regamma.arr_points[1].y,
-+ &fmt,
-+ &opp110->regamma.arr_points[1].custom_float_y)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!convert_to_custom_float_format(
-+ opp110->regamma.arr_points[2].slope,
-+ &fmt,
-+ &opp110->regamma.arr_points[2].custom_float_slope)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ fmt.mantissa_bits = 12;
-+ fmt.sign = true;
-+
-+ while (i != opp110->regamma.hw_points_num) {
-+ if (!convert_to_custom_float_format(
-+ rgb->red,
-+ &fmt,
-+ &rgb->red_reg)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!convert_to_custom_float_format(
-+ rgb->green,
-+ &fmt,
-+ &rgb->green_reg)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!convert_to_custom_float_format(
-+ rgb->blue,
-+ &fmt,
-+ &rgb->blue_reg)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!convert_to_custom_float_format(
-+ rgb->delta_red,
-+ &fmt,
-+ &rgb->delta_red_reg)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!convert_to_custom_float_format(
-+ rgb->delta_green,
-+ &fmt,
-+ &rgb->delta_green_reg)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!convert_to_custom_float_format(
-+ rgb->delta_blue,
-+ &fmt,
-+ &rgb->delta_blue_reg)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ ++rgb;
-+ ++i;
-+ }
-+
-+ return true;
-+}
-+
-+static bool round_custom_float_6_12(
-+ struct hw_x_point *x)
-+{
-+ struct custom_float_format fmt;
-+
-+ struct custom_float_value value;
-+
-+ fmt.exponenta_bits = 6;
-+ fmt.mantissa_bits = 12;
-+ fmt.sign = true;
-+
-+ if (!convert_to_custom_float_format_ex(
-+ x->x, &fmt, &value))
-+ return false;
-+
-+ x->adjusted_x = x->x;
-+
-+ if (value.mantissa) {
-+ BREAK_TO_DEBUGGER();
-+
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+static bool build_hw_curve_configuration(
-+ const struct curve_config *curve_config,
-+ struct gamma_curve *gamma_curve,
-+ struct curve_points *curve_points,
-+ struct hw_x_point *points,
-+ uint32_t *number_of_points)
-+{
-+ const int8_t max_regions_number = ARRAY_SIZE(curve_config->segments);
-+
-+ int8_t i;
-+
-+ uint8_t segments_calculation[8] = { 0 };
-+
-+ struct fixed31_32 region1 = dal_fixed31_32_zero;
-+ struct fixed31_32 region2;
-+ struct fixed31_32 increment;
-+
-+ uint32_t index = 0;
-+ uint32_t segments = 0;
-+ uint32_t max_number;
-+
-+ bool result = false;
-+
-+ if (!number_of_points) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ max_number = *number_of_points;
-+
-+ i = 0;
-+
-+ while (i != max_regions_number) {
-+ gamma_curve[i].offset = 0;
-+ gamma_curve[i].segments_num = 0;
-+
-+ ++i;
-+ }
-+
-+ i = 0;
-+
-+ while (i != max_regions_number) {
-+ /* number should go in uninterruptible sequence */
-+ if (curve_config->segments[i] == -1)
-+ break;
-+
-+ ASSERT(curve_config->segments[i] >= 0);
-+
-+ segments += (1 << curve_config->segments[i]);
-+
-+ ++i;
-+ }
-+
-+ if (segments > max_number) {
-+ BREAK_TO_DEBUGGER();
-+ } else {
-+ int32_t divisor;
-+ uint32_t offset = 0;
-+ int8_t begin = curve_config->begin;
-+ int32_t region_number = 0;
-+
-+ i = begin;
-+
-+ while ((index < max_number) &&
-+ (region_number < max_regions_number) &&
-+ (i <= 1)) {
-+ int32_t j = 0;
-+
-+ segments = curve_config->segments[region_number];
-+ divisor = 1 << segments;
-+
-+ if (segments == -1) {
-+ if (i > 0) {
-+ region1 = dal_fixed31_32_shl(
-+ dal_fixed31_32_one,
-+ i - 1);
-+ region2 = dal_fixed31_32_shl(
-+ dal_fixed31_32_one,
-+ i);
-+ } else {
-+ region1 = dal_fixed31_32_shr(
-+ dal_fixed31_32_one,
-+ -(i - 1));
-+ region2 = dal_fixed31_32_shr(
-+ dal_fixed31_32_one,
-+ -i);
-+ }
-+
-+ break;
-+ }
-+
-+ if (i > -1) {
-+ region1 = dal_fixed31_32_shl(
-+ dal_fixed31_32_one,
-+ i);
-+ region2 = dal_fixed31_32_shl(
-+ dal_fixed31_32_one,
-+ i + 1);
-+ } else {
-+ region1 = dal_fixed31_32_shr(
-+ dal_fixed31_32_one,
-+ -i);
-+ region2 = dal_fixed31_32_shr(
-+ dal_fixed31_32_one,
-+ -(i + 1));
-+ }
-+
-+ gamma_curve[region_number].offset = offset;
-+ gamma_curve[region_number].segments_num = segments;
-+
-+ offset += divisor;
-+
-+ ++segments_calculation[segments];
-+
-+ increment = dal_fixed31_32_div_int(
-+ dal_fixed31_32_sub(
-+ region2,
-+ region1),
-+ divisor);
-+
-+ points[index].x = region1;
-+
-+ round_custom_float_6_12(points + index);
-+
-+ ++index;
-+ ++region_number;
-+
-+ while ((index < max_number) && (j < divisor - 1)) {
-+ region1 = dal_fixed31_32_add(
-+ region1,
-+ increment);
-+
-+ points[index].x = region1;
-+ points[index].adjusted_x = region1;
-+
-+ ++index;
-+ ++j;
-+ }
-+
-+ ++i;
-+ }
-+
-+ points[index].x = region1;
-+
-+ round_custom_float_6_12(points + index);
-+
-+ *number_of_points = index;
-+
-+ result = true;
-+ }
-+
-+ curve_points[0].x = points[0].adjusted_x;
-+ curve_points[0].offset = dal_fixed31_32_zero;
-+
-+ curve_points[1].x = points[index - 1].adjusted_x;
-+ curve_points[1].offset = dal_fixed31_32_zero;
-+
-+ curve_points[2].x = points[index].adjusted_x;
-+ curve_points[2].offset = dal_fixed31_32_zero;
-+
-+ return result;
-+}
-+
-+static bool setup_distribution_points(
-+ struct dce110_opp *opp110)
-+{
-+ uint32_t hw_points_num = MAX_PWL_ENTRY * 2;
-+
-+ struct curve_config cfg;
-+
-+ cfg.offset = 0;
-+
-+ cfg.segments[0] = 3;
-+ cfg.segments[1] = 4;
-+ cfg.segments[2] = 4;
-+ cfg.segments[3] = 4;
-+ cfg.segments[4] = 4;
-+ cfg.segments[5] = 4;
-+ cfg.segments[6] = 4;
-+ cfg.segments[7] = 4;
-+ cfg.segments[8] = 5;
-+ cfg.segments[9] = 5;
-+ cfg.segments[10] = 0;
-+ cfg.segments[11] = -1;
-+ cfg.segments[12] = -1;
-+ cfg.segments[13] = -1;
-+ cfg.segments[14] = -1;
-+ cfg.segments[15] = -1;
-+
-+ cfg.begin = -10;
-+
-+ if (!build_hw_curve_configuration(
-+ &cfg, opp110->regamma.arr_curve_points,
-+ opp110->regamma.arr_points,
-+ opp110->regamma.coordinates_x, &hw_points_num)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ opp110->regamma.hw_points_num = hw_points_num;
-+
-+ return true;
-+}
-+
-+
-+/*
-+ *****************************************************************************
-+ * Function: regamma_config_regions_and_segments
-+ *
-+ * build regamma curve by using predefined hw points
-+ * uses interface parameters ,like EDID coeff.
-+ *
-+ * @param : parameters interface parameters
-+ * @return void
-+ *
-+ * @note
-+ *
-+ * @see
-+ *
-+ *****************************************************************************
-+ */
-+static void regamma_config_regions_and_segments(
-+ struct dce110_opp *opp110)
-+{
-+ struct gamma_curve *curve;
-+ uint32_t value = 0;
-+
-+ {
-+ set_reg_field_value(
-+ value,
-+ opp110->regamma.arr_points[0].custom_float_x,
-+ REGAMMA_CNTLA_START_CNTL,
-+ REGAMMA_CNTLA_EXP_REGION_START);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ REGAMMA_CNTLA_START_CNTL,
-+ REGAMMA_CNTLA_EXP_REGION_START_SEGMENT);
-+
-+ dal_write_reg(opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_START_CNTL),
-+ value);
-+ }
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ opp110->regamma.arr_points[0].custom_float_slope,
-+ REGAMMA_CNTLA_SLOPE_CNTL,
-+ REGAMMA_CNTLA_EXP_REGION_LINEAR_SLOPE);
-+
-+ dal_write_reg(opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_SLOPE_CNTL), value);
-+ }
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ opp110->regamma.arr_points[1].custom_float_x,
-+ REGAMMA_CNTLA_END_CNTL1,
-+ REGAMMA_CNTLA_EXP_REGION_END);
-+
-+ dal_write_reg(opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_END_CNTL1), value);
-+ }
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ opp110->regamma.arr_points[2].custom_float_slope,
-+ REGAMMA_CNTLA_END_CNTL2,
-+ REGAMMA_CNTLA_EXP_REGION_END_BASE);
-+
-+ set_reg_field_value(
-+ value,
-+ opp110->regamma.arr_points[1].custom_float_y,
-+ REGAMMA_CNTLA_END_CNTL2,
-+ REGAMMA_CNTLA_EXP_REGION_END_SLOPE);
-+
-+ dal_write_reg(opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_END_CNTL2), value);
-+ }
-+
-+ curve = opp110->regamma.arr_curve_points;
-+
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ curve[0].offset,
-+ REGAMMA_CNTLA_REGION_0_1,
-+ REGAMMA_CNTLA_EXP_REGION0_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[0].segments_num,
-+ REGAMMA_CNTLA_REGION_0_1,
-+ REGAMMA_CNTLA_EXP_REGION0_NUM_SEGMENTS);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].offset,
-+ REGAMMA_CNTLA_REGION_0_1,
-+ REGAMMA_CNTLA_EXP_REGION1_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].segments_num,
-+ REGAMMA_CNTLA_REGION_0_1,
-+ REGAMMA_CNTLA_EXP_REGION1_NUM_SEGMENTS);
-+
-+ dal_write_reg(
-+ opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_REGION_0_1),
-+ value);
-+ }
-+
-+ curve += 2;
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ curve[0].offset,
-+ REGAMMA_CNTLA_REGION_2_3,
-+ REGAMMA_CNTLA_EXP_REGION2_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[0].segments_num,
-+ REGAMMA_CNTLA_REGION_2_3,
-+ REGAMMA_CNTLA_EXP_REGION2_NUM_SEGMENTS);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].offset,
-+ REGAMMA_CNTLA_REGION_2_3,
-+ REGAMMA_CNTLA_EXP_REGION3_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].segments_num,
-+ REGAMMA_CNTLA_REGION_2_3,
-+ REGAMMA_CNTLA_EXP_REGION3_NUM_SEGMENTS);
-+
-+ dal_write_reg(opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_REGION_2_3),
-+ value);
-+ }
-+
-+ curve += 2;
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ curve[0].offset,
-+ REGAMMA_CNTLA_REGION_4_5,
-+ REGAMMA_CNTLA_EXP_REGION4_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[0].segments_num,
-+ REGAMMA_CNTLA_REGION_4_5,
-+ REGAMMA_CNTLA_EXP_REGION4_NUM_SEGMENTS);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].offset,
-+ REGAMMA_CNTLA_REGION_4_5,
-+ REGAMMA_CNTLA_EXP_REGION5_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].segments_num,
-+ REGAMMA_CNTLA_REGION_4_5,
-+ REGAMMA_CNTLA_EXP_REGION5_NUM_SEGMENTS);
-+
-+ dal_write_reg(opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_REGION_4_5),
-+ value);
-+ }
-+
-+ curve += 2;
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ curve[0].offset,
-+ REGAMMA_CNTLA_REGION_6_7,
-+ REGAMMA_CNTLA_EXP_REGION6_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[0].segments_num,
-+ REGAMMA_CNTLA_REGION_6_7,
-+ REGAMMA_CNTLA_EXP_REGION6_NUM_SEGMENTS);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].offset,
-+ REGAMMA_CNTLA_REGION_6_7,
-+ REGAMMA_CNTLA_EXP_REGION7_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].segments_num,
-+ REGAMMA_CNTLA_REGION_6_7,
-+ REGAMMA_CNTLA_EXP_REGION7_NUM_SEGMENTS);
-+
-+ dal_write_reg(opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_REGION_6_7),
-+ value);
-+ }
-+
-+ curve += 2;
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ curve[0].offset,
-+ REGAMMA_CNTLA_REGION_8_9,
-+ REGAMMA_CNTLA_EXP_REGION8_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[0].segments_num,
-+ REGAMMA_CNTLA_REGION_8_9,
-+ REGAMMA_CNTLA_EXP_REGION8_NUM_SEGMENTS);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].offset,
-+ REGAMMA_CNTLA_REGION_8_9,
-+ REGAMMA_CNTLA_EXP_REGION9_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].segments_num,
-+ REGAMMA_CNTLA_REGION_8_9,
-+ REGAMMA_CNTLA_EXP_REGION9_NUM_SEGMENTS);
-+
-+ dal_write_reg(opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_REGION_8_9),
-+ value);
-+ }
-+
-+ curve += 2;
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ curve[0].offset,
-+ REGAMMA_CNTLA_REGION_10_11,
-+ REGAMMA_CNTLA_EXP_REGION10_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[0].segments_num,
-+ REGAMMA_CNTLA_REGION_10_11,
-+ REGAMMA_CNTLA_EXP_REGION10_NUM_SEGMENTS);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].offset,
-+ REGAMMA_CNTLA_REGION_10_11,
-+ REGAMMA_CNTLA_EXP_REGION11_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].segments_num,
-+ REGAMMA_CNTLA_REGION_10_11,
-+ REGAMMA_CNTLA_EXP_REGION11_NUM_SEGMENTS);
-+
-+ dal_write_reg(opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_REGION_10_11),
-+ value);
-+ }
-+
-+ curve += 2;
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ curve[0].offset,
-+ REGAMMA_CNTLA_REGION_12_13,
-+ REGAMMA_CNTLA_EXP_REGION12_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[0].segments_num,
-+ REGAMMA_CNTLA_REGION_12_13,
-+ REGAMMA_CNTLA_EXP_REGION12_NUM_SEGMENTS);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].offset,
-+ REGAMMA_CNTLA_REGION_12_13,
-+ REGAMMA_CNTLA_EXP_REGION13_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].segments_num,
-+ REGAMMA_CNTLA_REGION_12_13,
-+ REGAMMA_CNTLA_EXP_REGION13_NUM_SEGMENTS);
-+
-+ dal_write_reg(opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_REGION_12_13),
-+ value);
-+ }
-+
-+ curve += 2;
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ curve[0].offset,
-+ REGAMMA_CNTLA_REGION_14_15,
-+ REGAMMA_CNTLA_EXP_REGION14_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[0].segments_num,
-+ REGAMMA_CNTLA_REGION_14_15,
-+ REGAMMA_CNTLA_EXP_REGION14_NUM_SEGMENTS);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].offset,
-+ REGAMMA_CNTLA_REGION_14_15,
-+ REGAMMA_CNTLA_EXP_REGION15_LUT_OFFSET);
-+
-+ set_reg_field_value(
-+ value,
-+ curve[1].segments_num,
-+ REGAMMA_CNTLA_REGION_14_15,
-+ REGAMMA_CNTLA_EXP_REGION15_NUM_SEGMENTS);
-+
-+ dal_write_reg(opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_REGION_14_15),
-+ value);
-+ }
-+}
-+
-+static void program_pwl(
-+ struct dce110_opp *opp110,
-+ const struct gamma_parameters *params)
-+{
-+ uint32_t value;
-+
-+ {
-+ uint8_t max_tries = 10;
-+ uint8_t counter = 0;
-+
-+ /* Power on LUT memory */
-+ value = dal_read_reg(opp110->base.ctx,
-+ DCFE_REG(mmDCFE_MEM_PWR_CTRL));
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DCFE_MEM_PWR_CTRL,
-+ DCP_REGAMMA_MEM_PWR_DIS);
-+
-+ dal_write_reg(opp110->base.ctx,
-+ DCFE_REG(mmDCFE_MEM_PWR_CTRL), value);
-+
-+ while (counter < max_tries) {
-+ value =
-+ dal_read_reg(
-+ opp110->base.ctx,
-+ DCFE_REG(mmDCFE_MEM_PWR_STATUS));
-+
-+ if (get_reg_field_value(
-+ value,
-+ DCFE_MEM_PWR_STATUS,
-+ DCP_REGAMMA_MEM_PWR_STATE) == 0)
-+ break;
-+
-+ ++counter;
-+ }
-+
-+ if (counter == max_tries) {
-+ dal_logger_write(opp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: regamma lut was not powered on "
-+ "in a timely manner,"
-+ " programming still proceeds\n",
-+ __func__);
-+ }
-+ }
-+
-+ value = 0;
-+
-+ set_reg_field_value(
-+ value,
-+ 7,
-+ REGAMMA_LUT_WRITE_EN_MASK,
-+ REGAMMA_LUT_WRITE_EN_MASK);
-+
-+ dal_write_reg(opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_LUT_WRITE_EN_MASK), value);
-+ dal_write_reg(opp110->base.ctx,
-+ DCP_REG(mmREGAMMA_LUT_INDEX), 0);
-+
-+ /* Program REGAMMA_LUT_DATA */
-+ {
-+ const uint32_t addr = DCP_REG(mmREGAMMA_LUT_DATA);
-+
-+ uint32_t i = 0;
-+
-+ struct pwl_result_data *rgb =
-+ opp110->regamma.rgb_resulted;
-+
-+ while (i != opp110->regamma.hw_points_num) {
-+ dal_write_reg(opp110->base.ctx, addr, rgb->red_reg);
-+ dal_write_reg(opp110->base.ctx, addr, rgb->green_reg);
-+ dal_write_reg(opp110->base.ctx, addr, rgb->blue_reg);
-+
-+ dal_write_reg(opp110->base.ctx, addr,
-+ rgb->delta_red_reg);
-+ dal_write_reg(opp110->base.ctx, addr,
-+ rgb->delta_green_reg);
-+ dal_write_reg(opp110->base.ctx, addr,
-+ rgb->delta_blue_reg);
-+
-+ ++rgb;
-+ ++i;
-+ }
-+ }
-+
-+ /* we are done with DCP LUT memory; re-enable low power mode */
-+ value = dal_read_reg(opp110->base.ctx, DCFE_REG(mmDCFE_MEM_PWR_CTRL));
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DCFE_MEM_PWR_CTRL,
-+ DCP_REGAMMA_MEM_PWR_DIS);
-+
-+ dal_write_reg(opp110->base.ctx, DCFE_REG(mmDCFE_MEM_PWR_CTRL), value);
-+}
-+
-+void dce110_opp_power_on_regamma_lut(
-+ struct output_pixel_processor *opp,
-+ bool power_on)
-+{
-+ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
-+
-+ uint32_t value =
-+ dal_read_reg(opp->ctx, DCFE_REG(mmDCFE_MEM_PWR_CTRL));
-+
-+ set_reg_field_value(
-+ value,
-+ power_on,
-+ DCFE_MEM_PWR_CTRL,
-+ DCP_REGAMMA_MEM_PWR_DIS);
-+
-+ set_reg_field_value(
-+ value,
-+ power_on,
-+ DCFE_MEM_PWR_CTRL,
-+ DCP_LUT_MEM_PWR_DIS);
-+
-+ dal_write_reg(opp->ctx, DCFE_REG(mmDCFE_MEM_PWR_CTRL), value);
-+}
-+
-+static bool scale_gamma(
-+ struct dce110_opp *opp110,
-+ const struct gamma_ramp *gamma_ramp,
-+ const struct gamma_parameters *params)
-+{
-+ const struct gamma_ramp_rgb256x3x16 *gamma;
-+ bool use_palette = params->surface_pixel_format == PIXEL_FORMAT_INDEX8;
-+
-+ const uint16_t max_driver = 0xFFFF;
-+ const uint16_t max_os = 0xFF00;
-+
-+ uint16_t scaler = max_os;
-+
-+ uint32_t i;
-+
-+ struct dev_c_lut *palette = opp110->regamma.saved_palette;
-+
-+ struct pwl_float_data *rgb = opp110->regamma.rgb_user;
-+ struct pwl_float_data *rgb_last = rgb + RGB_256X3X16 - 1;
-+
-+ if (gamma_ramp->type == GAMMA_RAMP_RBG256X3X16)
-+ gamma = &gamma_ramp->gamma_ramp_rgb256x3x16;
-+ else
-+ return false; /* invalid option */
-+
-+ i = 0;
-+
-+ do {
-+ if ((gamma->red[i] > max_os) ||
-+ (gamma->green[i] > max_os) ||
-+ (gamma->blue[i] > max_os)) {
-+ scaler = max_driver;
-+ break;
-+ }
-+ ++i;
-+ } while (i != RGB_256X3X16);
-+
-+ i = 0;
-+
-+ if (use_palette)
-+ do {
-+ rgb->r = dal_fixed31_32_from_fraction(
-+ gamma->red[palette->red], scaler);
-+ rgb->g = dal_fixed31_32_from_fraction(
-+ gamma->green[palette->green], scaler);
-+ rgb->b = dal_fixed31_32_from_fraction(
-+ gamma->blue[palette->blue], scaler);
-+
-+ ++palette;
-+ ++rgb;
-+ ++i;
-+ } while (i != RGB_256X3X16);
-+ else
-+ do {
-+ rgb->r = dal_fixed31_32_from_fraction(
-+ gamma->red[i], scaler);
-+ rgb->g = dal_fixed31_32_from_fraction(
-+ gamma->green[i], scaler);
-+ rgb->b = dal_fixed31_32_from_fraction(
-+ gamma->blue[i], scaler);
-+
-+ ++rgb;
-+ ++i;
-+ } while (i != RGB_256X3X16);
-+
-+ rgb->r = dal_fixed31_32_mul(rgb_last->r,
-+ opp110->regamma.divider1);
-+ rgb->g = dal_fixed31_32_mul(rgb_last->g,
-+ opp110->regamma.divider1);
-+ rgb->b = dal_fixed31_32_mul(rgb_last->b,
-+ opp110->regamma.divider1);
-+
-+ ++rgb;
-+
-+ rgb->r = dal_fixed31_32_mul(rgb_last->r,
-+ opp110->regamma.divider2);
-+ rgb->g = dal_fixed31_32_mul(rgb_last->g,
-+ opp110->regamma.divider2);
-+ rgb->b = dal_fixed31_32_mul(rgb_last->b,
-+ opp110->regamma.divider2);
-+
-+ ++rgb;
-+
-+ rgb->r = dal_fixed31_32_mul(rgb_last->r,
-+ opp110->regamma.divider3);
-+ rgb->g = dal_fixed31_32_mul(rgb_last->g,
-+ opp110->regamma.divider3);
-+ rgb->b = dal_fixed31_32_mul(rgb_last->b,
-+ opp110->regamma.divider3);
-+
-+ return true;
-+}
-+
-+
-+static void configure_regamma_mode(
-+ struct dce110_opp *opp110,
-+ const struct gamma_parameters *params,
-+ bool force_bypass)
-+{
-+ const uint32_t addr = DCP_REG(mmREGAMMA_CONTROL);
-+
-+ enum wide_gamut_regamma_mode mode =
-+ WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_MATRIX_A;
-+
-+ uint32_t value = dal_read_reg(opp110->base.ctx, addr);
-+
-+ if (force_bypass) {
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ REGAMMA_CONTROL,
-+ GRPH_REGAMMA_MODE);
-+
-+ dal_write_reg(opp110->base.ctx, addr, value);
-+
-+ return;
-+ }
-+
-+ if (params->regamma_adjust_type == GRAPHICS_REGAMMA_ADJUST_BYPASS)
-+ mode = WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_BYPASS;
-+ else if (params->regamma_adjust_type == GRAPHICS_REGAMMA_ADJUST_HW) {
-+ if (params->surface_pixel_format == PIXEL_FORMAT_FP16)
-+ mode = WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_BYPASS;
-+ else
-+ mode = WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_SRGB24;
-+ }
-+
-+ switch (mode) {
-+ case WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_BYPASS:
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ REGAMMA_CONTROL,
-+ GRPH_REGAMMA_MODE);
-+ break;
-+ case WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_SRGB24:
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ REGAMMA_CONTROL,
-+ GRPH_REGAMMA_MODE);
-+ break;
-+ case WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_XYYCC22:
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ REGAMMA_CONTROL,
-+ GRPH_REGAMMA_MODE);
-+ break;
-+ case WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_MATRIX_A:
-+ set_reg_field_value(
-+ value,
-+ 3,
-+ REGAMMA_CONTROL,
-+ GRPH_REGAMMA_MODE);
-+ break;
-+ case WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_MATRIX_B:
-+ set_reg_field_value(
-+ value,
-+ 4,
-+ REGAMMA_CONTROL,
-+ GRPH_REGAMMA_MODE);
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ dal_write_reg(opp110->base.ctx, addr, value);
-+}
-+
-+bool dce110_opp_set_regamma(
-+ struct output_pixel_processor *opp,
-+ const struct gamma_ramp *ramp,
-+ const struct gamma_parameters *params,
-+ bool force_bypass)
-+{
-+ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
-+
-+ if (force_bypass) {
-+ configure_regamma_mode(opp110, params, true);
-+ } else {
-+ /* 1. Scale gamma to 0 - 1 to m_pRgbUser */
-+ if (!scale_gamma(opp110, ramp, params)) {
-+ ASSERT_CRITICAL(false);
-+ /* invalid option */
-+ return false;
-+ }
-+
-+ /* 2. Configure regamma curve without analysis (future task) */
-+ /* and program the PWL regions and segments */
-+ if (params->regamma_adjust_type == GRAPHICS_REGAMMA_ADJUST_SW ||
-+ params->surface_pixel_format == PIXEL_FORMAT_FP16) {
-+
-+ /* 3. Setup x exponentially distributed points */
-+ if (!setup_distribution_points(opp110)) {
-+ ASSERT_CRITICAL(false);
-+ /* invalid option */
-+ return false;
-+ }
-+
-+ /* 4. Build ideal regamma curve */
-+ if (!build_regamma_curve(opp110, params)) {
-+ ASSERT_CRITICAL(false);
-+ /* invalid parameters or bug */
-+ return false;
-+ }
-+
-+ /* 5. Map user gamma (evenly distributed x points) to
-+ * new curve when x is y from ideal regamma , step 5 */
-+ if (!map_regamma_hw_to_x_user(
-+ opp110, ramp, params)) {
-+ ASSERT_CRITICAL(false);
-+ /* invalid parameters or bug */
-+ return false;
-+ }
-+
-+ /* 6.Build and verify resulted curve */
-+ build_new_custom_resulted_curve(opp110, params);
-+
-+ /* 7. Build and translate x to hw format */
-+ if (!rebuild_curve_configuration_magic(opp110)) {
-+ ASSERT_CRITICAL(false);
-+ /* invalid parameters or bug */
-+ return false;
-+ }
-+
-+ /* 8. convert all params to the custom float format */
-+ if (!convert_to_custom_float(opp110)) {
-+ ASSERT_CRITICAL(false);
-+ /* invalid parameters or bug */
-+ return false;
-+ }
-+
-+ /* 9. program regamma curve configuration */
-+ regamma_config_regions_and_segments(opp110);
-+
-+ /* 10. Program PWL */
-+ program_pwl(opp110, params);
-+ }
-+
-+ /*
-+ * 11. program regamma config
-+ */
-+ configure_regamma_mode(opp110, params, false);
-+ }
-+ return true;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
-new file mode 100644
-index 0000000..d2594a9
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
-@@ -0,0 +1,1276 @@
-+/*
-+* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#include "dc_services.h"
-+
-+#include "resource.h"
-+#include "include/irq_service_interface.h"
-+#include "dce110/dce110_timing_generator.h"
-+#include "dce110/dce110_link_encoder.h"
-+#include "dce110/dce110_mem_input.h"
-+#include "dce110/dce110_ipp.h"
-+#include "dce110/dce110_transform.h"
-+#include "dce110/dce110_stream_encoder.h"
-+#include "dce110/dce110_opp.h"
-+#include "link_encoder_types.h"
-+#include "stream_encoder_types.h"
-+
-+enum dce110_clk_src_array_id {
-+ DCE110_CLK_SRC_PLL0 = 0,
-+ DCE110_CLK_SRC_PLL1,
-+ DCE110_CLK_SRC_EXT,
-+
-+ DCE110_CLK_SRC_TOTAL
-+};
-+
-+static void set_vendor_info_packet(struct core_stream *stream,
-+ struct hw_info_packet *info_packet)
-+{
-+ uint32_t length = 0;
-+ bool hdmi_vic_mode = false;
-+ uint8_t checksum = 0;
-+ uint32_t i = 0;
-+ enum dc_timing_3d_format format;
-+
-+ ASSERT_CRITICAL(stream != NULL);
-+ ASSERT_CRITICAL(info_packet != NULL);
-+
-+ format = stream->public.timing.timing_3d_format;
-+
-+ /* Can be different depending on packet content */
-+ length = 5;
-+
-+ if (stream->public.timing.hdmi_vic != 0
-+ && stream->public.timing.h_total >= 3840
-+ && stream->public.timing.v_total >= 2160)
-+ hdmi_vic_mode = true;
-+
-+ /* According to HDMI 1.4a CTS, VSIF should be sent
-+ * for both 3D stereo and HDMI VIC modes.
-+ * For all other modes, there is no VSIF sent. */
-+
-+ if (format == TIMING_3D_FORMAT_NONE && !hdmi_vic_mode)
-+ return;
-+
-+ /* 24bit IEEE Registration identifier (0x000c03). LSB first. */
-+ info_packet->sb[1] = 0x03;
-+ info_packet->sb[2] = 0x0C;
-+ info_packet->sb[3] = 0x00;
-+
-+ /*PB4: 5 lower bytes = 0 (reserved). 3 higher bits = HDMI_Video_Format.
-+ * The value for HDMI_Video_Format are:
-+ * 0x0 (0b000) - No additional HDMI video format is presented in this
-+ * packet
-+ * 0x1 (0b001) - Extended resolution format present. 1 byte of HDMI_VIC
-+ * parameter follows
-+ * 0x2 (0b010) - 3D format indication present. 3D_Structure and
-+ * potentially 3D_Ext_Data follows
-+ * 0x3..0x7 (0b011..0b111) - reserved for future use */
-+ if (format != TIMING_3D_FORMAT_NONE)
-+ info_packet->sb[4] = (2 << 5);
-+ else if (hdmi_vic_mode)
-+ info_packet->sb[4] = (1 << 5);
-+
-+ /* PB5: If PB4 claims 3D timing (HDMI_Video_Format = 0x2):
-+ * 4 lower bites = 0 (reserved). 4 higher bits = 3D_Structure.
-+ * The value for 3D_Structure are:
-+ * 0x0 - Frame Packing
-+ * 0x1 - Field Alternative
-+ * 0x2 - Line Alternative
-+ * 0x3 - Side-by-Side (full)
-+ * 0x4 - L + depth
-+ * 0x5 - L + depth + graphics + graphics-depth
-+ * 0x6 - Top-and-Bottom
-+ * 0x7 - Reserved for future use
-+ * 0x8 - Side-by-Side (Half)
-+ * 0x9..0xE - Reserved for future use
-+ * 0xF - Not used */
-+ switch (format) {
-+ case TIMING_3D_FORMAT_HW_FRAME_PACKING:
-+ case TIMING_3D_FORMAT_SW_FRAME_PACKING:
-+ info_packet->sb[5] = (0x0 << 4);
-+ break;
-+
-+ case TIMING_3D_FORMAT_SIDE_BY_SIDE:
-+ case TIMING_3D_FORMAT_SBS_SW_PACKED:
-+ info_packet->sb[5] = (0x8 << 4);
-+ length = 6;
-+ break;
-+
-+ case TIMING_3D_FORMAT_TOP_AND_BOTTOM:
-+ case TIMING_3D_FORMAT_TB_SW_PACKED:
-+ info_packet->sb[5] = (0x6 << 4);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ /*PB5: If PB4 is set to 0x1 (extended resolution format)
-+ * fill PB5 with the correct HDMI VIC code */
-+ if (hdmi_vic_mode)
-+ info_packet->sb[5] = stream->public.timing.hdmi_vic;
-+
-+ /* Header */
-+ info_packet->hb0 = 0x81; /* VSIF packet type. */
-+ info_packet->hb1 = 0x01; /* Version */
-+
-+ /* 4 lower bits = Length, 4 higher bits = 0 (reserved) */
-+ info_packet->hb2 = (uint8_t) (length);
-+
-+ /* Calculate checksum */
-+ checksum = 0;
-+ checksum += info_packet->hb0;
-+ checksum += info_packet->hb1;
-+ checksum += info_packet->hb2;
-+
-+ for (i = 1; i <= length; i++)
-+ checksum += info_packet->sb[i];
-+
-+ info_packet->sb[0] = (uint8_t) (0x100 - checksum);
-+
-+ info_packet->valid = true;
-+}
-+
-+static enum ds_color_space build_default_color_space(
-+ struct core_stream *stream)
-+{
-+ enum ds_color_space color_space =
-+ DS_COLOR_SPACE_SRGB_FULLRANGE;
-+ struct dc_crtc_timing *timing = &stream->public.timing;
-+
-+ switch (stream->signal) {
-+ /* TODO: implement other signal color space setting */
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP:
-+ break;
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ {
-+ uint32_t pix_clk_khz;
-+
-+ if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422 &&
-+ timing->pixel_encoding == PIXEL_ENCODING_YCBCR444) {
-+ if (timing->timing_standard ==
-+ TIMING_STANDARD_CEA770 &&
-+ timing->timing_standard ==
-+ TIMING_STANDARD_CEA861)
-+ color_space = DS_COLOR_SPACE_SRGB_FULLRANGE;
-+
-+ pix_clk_khz = timing->pix_clk_khz / 10;
-+ if (timing->h_addressable == 640 &&
-+ timing->v_addressable == 480 &&
-+ (pix_clk_khz == 2520 || pix_clk_khz == 2517))
-+ color_space = DS_COLOR_SPACE_SRGB_FULLRANGE;
-+ } else {
-+ if (timing->timing_standard ==
-+ TIMING_STANDARD_CEA770 ||
-+ timing->timing_standard ==
-+ TIMING_STANDARD_CEA861) {
-+
-+ color_space =
-+ (timing->pix_clk_khz > PIXEL_CLOCK) ?
-+ DS_COLOR_SPACE_YCBCR709 :
-+ DS_COLOR_SPACE_YCBCR601;
-+ }
-+ }
-+ break;
-+ }
-+ default:
-+ switch (timing->pixel_encoding) {
-+ case PIXEL_ENCODING_YCBCR422:
-+ case PIXEL_ENCODING_YCBCR444:
-+ if (timing->pix_clk_khz > PIXEL_CLOCK)
-+ color_space = DS_COLOR_SPACE_YCBCR709;
-+ else
-+ color_space = DS_COLOR_SPACE_YCBCR601;
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+ }
-+ return color_space;
-+}
-+
-+static void set_avi_info_frame(struct hw_info_packet *info_packet,
-+ struct core_stream *stream)
-+{
-+ enum ds_color_space color_space = DS_COLOR_SPACE_UNKNOWN;
-+ struct info_frame info_frame = { {0} };
-+ uint32_t pixel_encoding = 0;
-+ enum scanning_type scan_type = SCANNING_TYPE_NODATA;
-+ enum dc_aspect_ratio aspect = ASPECT_RATIO_NO_DATA;
-+ bool itc = false;
-+ uint8_t cn0_cn1 = 0;
-+ uint8_t *check_sum = NULL;
-+ uint8_t byte_index = 0;
-+
-+ if (info_packet == NULL)
-+ return;
-+
-+ color_space = build_default_color_space(stream);
-+
-+ /* Initialize header */
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.header.
-+ info_frame_type = INFO_FRAME_AVI;
-+ /* InfoFrameVersion_3 is defined by CEA861F (Section 6.4), but shall
-+ * not be used in HDMI 2.0 (Section 10.1) */
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.header.version =
-+ INFO_FRAME_VERSION_2;
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.header.length =
-+ INFO_FRAME_SIZE_AVI;
-+
-+ /* IDO-defined (Y2,Y1,Y0 = 1,1,1) shall not be used by devices built
-+ * according to HDMI 2.0 spec (Section 10.1)
-+ * Add "case PixelEncoding_YCbCr420: pixelEncoding = 3; break;"
-+ * when YCbCr 4:2:0 is supported by DAL hardware. */
-+
-+ switch (stream->public.timing.pixel_encoding) {
-+ case PIXEL_ENCODING_YCBCR422:
-+ pixel_encoding = 1;
-+ break;
-+
-+ case PIXEL_ENCODING_YCBCR444:
-+ pixel_encoding = 2;
-+ break;
-+
-+ case PIXEL_ENCODING_RGB:
-+ default:
-+ pixel_encoding = 0;
-+ }
-+
-+ /* Y0_Y1_Y2 : The pixel encoding */
-+ /* H14b AVI InfoFrame has extension on Y-field from 2 bits to 3 bits */
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.Y0_Y1_Y2 =
-+ pixel_encoding;
-+
-+
-+ /* A0 = 1 Active Format Information valid */
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.A0 =
-+ ACTIVE_FORMAT_VALID;
-+
-+ /* B0, B1 = 3; Bar info data is valid */
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.B0_B1 =
-+ BAR_INFO_BOTH_VALID;
-+
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.SC0_SC1 =
-+ PICTURE_SCALING_UNIFORM;
-+
-+ /* S0, S1 : Underscan / Overscan */
-+ /* TODO: un-hardcode scan type */
-+ scan_type = SCANNING_TYPE_UNDERSCAN;
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.S0_S1 = scan_type;
-+
-+ /* C0, C1 : Colorimetry */
-+ if (color_space == DS_COLOR_SPACE_YCBCR709)
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 =
-+ COLORIMETRY_ITU709;
-+ else if (color_space == DS_COLOR_SPACE_YCBCR601)
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 =
-+ COLORIMETRY_ITU601;
-+ else
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.C0_C1 =
-+ COLORIMETRY_NO_DATA;
-+
-+
-+ /* TODO: un-hardcode aspect ratio */
-+ aspect = stream->public.timing.aspect_ratio;
-+
-+ switch (aspect) {
-+ case ASPECT_RATIO_4_3:
-+ case ASPECT_RATIO_16_9:
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.M0_M1 = aspect;
-+ break;
-+
-+ case ASPECT_RATIO_NO_DATA:
-+ case ASPECT_RATIO_64_27:
-+ case ASPECT_RATIO_256_135:
-+ default:
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.M0_M1 = 0;
-+ }
-+
-+ /* Active Format Aspect ratio - same as Picture Aspect Ratio. */
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.R0_R3 =
-+ ACTIVE_FORMAT_ASPECT_RATIO_SAME_AS_PICTURE;
-+
-+ /* TODO: un-hardcode cn0_cn1 and itc */
-+ cn0_cn1 = 0;
-+ itc = false;
-+
-+ if (itc) {
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.ITC = 1;
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.CN0_CN1 =
-+ cn0_cn1;
-+ }
-+
-+ /* TODO: un-hardcode q0_q1 */
-+ if (color_space == DS_COLOR_SPACE_SRGB_FULLRANGE)
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.Q0_Q1 =
-+ RGB_QUANTIZATION_FULL_RANGE;
-+ else if (color_space == DS_COLOR_SPACE_SRGB_LIMITEDRANGE)
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.Q0_Q1 =
-+ RGB_QUANTIZATION_LIMITED_RANGE;
-+ else
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.Q0_Q1 =
-+ RGB_QUANTIZATION_DEFAULT_RANGE;
-+
-+ /* TODO : We should handle YCC quantization,
-+ * but we do not have matrix calculation */
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.YQ0_YQ1 =
-+ YYC_QUANTIZATION_LIMITED_RANGE;
-+
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.VIC0_VIC7 =
-+ stream->public.timing.vic;
-+
-+ /* pixel repetition
-+ * PR0 - PR3 start from 0 whereas pHwPathMode->mode.timing.flags.pixel
-+ * repetition start from 1 */
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.PR0_PR3 = 0;
-+
-+ /* Bar Info
-+ * barTop: Line Number of End of Top Bar.
-+ * barBottom: Line Number of Start of Bottom Bar.
-+ * barLeft: Pixel Number of End of Left Bar.
-+ * barRight: Pixel Number of Start of Right Bar. */
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.bar_top =
-+ stream->public.timing.v_border_top;
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.bar_bottom =
-+ (stream->public.timing.v_border_top
-+ - stream->public.timing.v_border_bottom + 1);
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.bar_left =
-+ stream->public.timing.h_border_left;
-+ info_frame.avi_info_packet.info_packet_hdmi.bits.bar_right =
-+ (stream->public.timing.h_total
-+ - stream->public.timing.h_border_right + 1);
-+
-+ /* check_sum - Calculate AFMT_AVI_INFO0 ~ AFMT_AVI_INFO3 */
-+ check_sum =
-+ &info_frame.
-+ avi_info_packet.info_packet_hdmi.packet_raw_data.sb[0];
-+ *check_sum = INFO_FRAME_AVI + INFO_FRAME_SIZE_AVI
-+ + INFO_FRAME_VERSION_2;
-+
-+ for (byte_index = 1; byte_index <= INFO_FRAME_SIZE_AVI; byte_index++)
-+ *check_sum += info_frame.avi_info_packet.info_packet_hdmi.
-+ packet_raw_data.sb[byte_index];
-+
-+ /* one byte complement */
-+ *check_sum = (uint8_t) (0x100 - *check_sum);
-+
-+ /* Store in hw_path_mode */
-+ info_packet->hb0 =
-+ info_frame.avi_info_packet.info_packet_hdmi.packet_raw_data.hb0;
-+ info_packet->hb1 =
-+ info_frame.avi_info_packet.info_packet_hdmi.packet_raw_data.hb1;
-+ info_packet->hb2 =
-+ info_frame.avi_info_packet.info_packet_hdmi.packet_raw_data.hb2;
-+
-+ for (byte_index = 0; byte_index < sizeof(info_packet->sb); byte_index++)
-+ info_packet->sb[byte_index] = info_frame.avi_info_packet.
-+ info_packet_hdmi.packet_raw_data.sb[byte_index];
-+
-+ info_packet->valid = true;
-+}
-+
-+static void translate_info_frame(const struct hw_info_frame *hw_info_frame,
-+ struct encoder_info_frame *encoder_info_frame)
-+{
-+ dc_service_memset(
-+ encoder_info_frame, 0, sizeof(struct encoder_info_frame));
-+
-+ /* For gamut we recalc checksum */
-+ if (hw_info_frame->gamut_packet.valid) {
-+ uint8_t chk_sum = 0;
-+ uint8_t *ptr;
-+ uint8_t i;
-+
-+ dc_service_memmove(
-+ &encoder_info_frame->gamut,
-+ &hw_info_frame->gamut_packet,
-+ sizeof(struct hw_info_packet));
-+
-+ /*start of the Gamut data. */
-+ ptr = &encoder_info_frame->gamut.sb[3];
-+
-+ for (i = 0; i <= encoder_info_frame->gamut.sb[1]; i++)
-+ chk_sum += ptr[i];
-+
-+ encoder_info_frame->gamut.sb[2] = (uint8_t) (0x100 - chk_sum);
-+ }
-+
-+ if (hw_info_frame->avi_info_packet.valid) {
-+ dc_service_memmove(
-+ &encoder_info_frame->avi,
-+ &hw_info_frame->avi_info_packet,
-+ sizeof(struct hw_info_packet));
-+ }
-+
-+ if (hw_info_frame->vendor_info_packet.valid) {
-+ dc_service_memmove(
-+ &encoder_info_frame->vendor,
-+ &hw_info_frame->vendor_info_packet,
-+ sizeof(struct hw_info_packet));
-+ }
-+
-+ if (hw_info_frame->spd_packet.valid) {
-+ dc_service_memmove(
-+ &encoder_info_frame->spd,
-+ &hw_info_frame->spd_packet,
-+ sizeof(struct hw_info_packet));
-+ }
-+
-+ if (hw_info_frame->vsc_packet.valid) {
-+ dc_service_memmove(
-+ &encoder_info_frame->vsc,
-+ &hw_info_frame->vsc_packet,
-+ sizeof(struct hw_info_packet));
-+ }
-+}
-+
-+static void build_info_frame(struct core_stream *stream)
-+{
-+ enum signal_type signal = SIGNAL_TYPE_NONE;
-+ struct hw_info_frame info_frame = { { 0 } };
-+
-+ /* default all packets to invalid */
-+ info_frame.avi_info_packet.valid = false;
-+ info_frame.gamut_packet.valid = false;
-+ info_frame.vendor_info_packet.valid = false;
-+ info_frame.spd_packet.valid = false;
-+ info_frame.vsc_packet.valid = false;
-+
-+ signal = stream->sink->public.sink_signal;
-+
-+ /* HDMi and DP have different info packets*/
-+ if (signal == SIGNAL_TYPE_HDMI_TYPE_A) {
-+ set_avi_info_frame(&info_frame.avi_info_packet,
-+ stream);
-+ set_vendor_info_packet(stream, &info_frame.vendor_info_packet);
-+ }
-+
-+ translate_info_frame(&info_frame,
-+ &stream->encoder_info_frame);
-+}
-+
-+
-+bool dce110_construct_resource_pool(
-+ struct adapter_service *adapter_serv,
-+ struct dc *dc,
-+ struct resource_pool *pool)
-+{
-+ unsigned int i;
-+ struct clock_source_init_data clk_src_init_data = { 0 };
-+ struct audio_init_data audio_init_data = { 0 };
-+ struct dc_context *ctx = dc->ctx;
-+ pool->adapter_srv = adapter_serv;
-+
-+ pool->stream_engines.engine.ENGINE_ID_DIGA = 1;
-+ pool->stream_engines.engine.ENGINE_ID_DIGB = 1;
-+ pool->stream_engines.engine.ENGINE_ID_DIGC = 1;
-+
-+ clk_src_init_data.as = adapter_serv;
-+ clk_src_init_data.ctx = ctx;
-+ clk_src_init_data.clk_src_id.enum_id = ENUM_ID_1;
-+ clk_src_init_data.clk_src_id.type = OBJECT_TYPE_CLOCK_SOURCE;
-+ pool->clk_src_count = DCE110_CLK_SRC_TOTAL;
-+
-+ clk_src_init_data.clk_src_id.id = CLOCK_SOURCE_ID_PLL0;
-+ pool->clock_sources[DCE110_CLK_SRC_PLL0] = dal_clock_source_create(
-+ &clk_src_init_data);
-+ clk_src_init_data.clk_src_id.id = CLOCK_SOURCE_ID_PLL1;
-+ pool->clock_sources[DCE110_CLK_SRC_PLL1] = dal_clock_source_create(
-+ &clk_src_init_data);
-+ clk_src_init_data.clk_src_id.id = CLOCK_SOURCE_ID_EXTERNAL;
-+ pool->clock_sources[DCE110_CLK_SRC_EXT] = dal_clock_source_create(
-+ &clk_src_init_data);
-+
-+ for (i = 0; i < pool->clk_src_count; i++) {
-+ if (pool->clock_sources[i] == NULL) {
-+ dal_error("DC: failed to create clock sources!\n");
-+ BREAK_TO_DEBUGGER();
-+ goto clk_src_create_fail;
-+ }
-+ }
-+
-+ pool->display_clock = dal_display_clock_dce110_create(ctx, adapter_serv);
-+ if (pool->display_clock == NULL) {
-+ dal_error("DC: failed to create display clock!\n");
-+ BREAK_TO_DEBUGGER();
-+ goto disp_clk_create_fail;
-+ }
-+
-+ {
-+ struct irq_service_init_data init_data;
-+ init_data.ctx = dc->ctx;
-+ pool->irqs = dal_irq_service_create(
-+ dal_adapter_service_get_dce_version(
-+ dc->res_pool.adapter_srv),
-+ &init_data);
-+ if (!pool->irqs)
-+ goto irqs_create_fail;
-+
-+ }
-+
-+ pool->controller_count =
-+ dal_adapter_service_get_func_controllers_num(adapter_serv);
-+ pool->stream_enc_count = 3;
-+ pool->scaler_filter = dal_scaler_filter_create(ctx);
-+ if (pool->scaler_filter == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dal_error("DC: failed to create filter!\n");
-+ goto filter_create_fail;
-+ }
-+
-+ for (i = 0; i < pool->controller_count; i++) {
-+ pool->timing_generators[i] = dce110_timing_generator_create(
-+ adapter_serv,
-+ ctx,
-+ i + 1);
-+ if (pool->timing_generators[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dal_error("DC: failed to create tg!\n");
-+ goto controller_create_fail;
-+ }
-+
-+ pool->mis[i] = dce110_mem_input_create(
-+ ctx,
-+ i + 1);
-+ if (pool->mis[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dal_error(
-+ "DC: failed to create memory input!\n");
-+ goto controller_create_fail;
-+ }
-+
-+ pool->ipps[i] = dce110_ipp_create(
-+ ctx,
-+ i + 1);
-+ if (pool->ipps[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dal_error(
-+ "DC: failed to create input pixel processor!\n");
-+ goto controller_create_fail;
-+ }
-+
-+ pool->transforms[i] = dce110_transform_create(
-+ ctx,
-+ i + 1);
-+ if (pool->transforms[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dal_error(
-+ "DC: failed to create transform!\n");
-+ goto controller_create_fail;
-+ }
-+ dce110_transform_set_scaler_filter(
-+ pool->transforms[i],
-+ pool->scaler_filter);
-+
-+ pool->opps[i] = dce110_opp_create(
-+ ctx,
-+ i + 1);
-+ if (pool->opps[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dal_error(
-+ "DC: failed to create output pixel processor!\n");
-+ goto controller_create_fail;
-+ }
-+ }
-+
-+ audio_init_data.as = adapter_serv;
-+ audio_init_data.ctx = ctx;
-+ pool->audio_count = 0;
-+ for (i = 0; i < pool->controller_count; i++) {
-+ struct graphics_object_id obj_id;
-+
-+ obj_id = dal_adapter_service_enum_audio_object(adapter_serv, i);
-+ if (false == dal_graphics_object_id_is_valid(obj_id)) {
-+ /* no more valid audio objects */
-+ break;
-+ }
-+
-+ audio_init_data.audio_stream_id = obj_id;
-+ pool->audios[i] = dal_audio_create(&audio_init_data);
-+ if (pool->audios[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dal_error("DC: failed to create DPPs!\n");
-+ goto audio_create_fail;
-+ }
-+ pool->audio_count++;
-+ }
-+
-+ for (i = 0; i < pool->stream_enc_count; i++) {
-+ struct stream_enc_init_data enc_init_data = { 0 };
-+ /* TODO: rework fragile code*/
-+ enc_init_data.stream_engine_id = i;
-+ enc_init_data.adapter_service = adapter_serv;
-+ enc_init_data.ctx = dc->ctx;
-+ if (pool->stream_engines.u_all & 1 << i) {
-+ pool->stream_enc[i] = dce110_stream_encoder_create(
-+ &enc_init_data);
-+
-+ if (pool->stream_enc[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dal_error("DC: failed to create stream_encoder!\n");
-+ goto stream_enc_create_fail;
-+ }
-+ }
-+ }
-+
-+ return true;
-+
-+stream_enc_create_fail:
-+ for (i = 0; i < pool->stream_enc_count; i++) {
-+ if (pool->stream_enc[i] != NULL)
-+ dce110_stream_encoder_destroy(&pool->stream_enc[i]);
-+ }
-+
-+audio_create_fail:
-+ for (i = 0; i < pool->controller_count; i++) {
-+ if (pool->audios[i] != NULL)
-+ dal_audio_destroy(&pool->audios[i]);
-+ }
-+
-+controller_create_fail:
-+ for (i = 0; i < pool->controller_count; i++) {
-+ if (pool->opps[i] != NULL)
-+ dce110_opp_destroy(&pool->opps[i]);
-+
-+ if (pool->transforms[i] != NULL)
-+ dce110_transform_destroy(&pool->transforms[i]);
-+
-+ if (pool->ipps[i] != NULL)
-+ dce110_ipp_destroy(&pool->ipps[i]);
-+
-+ if (pool->mis[i] != NULL)
-+ dce110_mem_input_destroy(&pool->mis[i]);
-+
-+ if (pool->timing_generators[i] != NULL)
-+ dce110_timing_generator_destroy(
-+ &pool->timing_generators[i]);
-+ }
-+
-+filter_create_fail:
-+ dal_irq_service_destroy(&pool->irqs);
-+
-+irqs_create_fail:
-+ dal_display_clock_destroy(&pool->display_clock);
-+
-+disp_clk_create_fail:
-+clk_src_create_fail:
-+ for (i = 0; i < pool->clk_src_count; i++) {
-+ if (pool->clock_sources[i] != NULL)
-+ dal_clock_source_destroy(&pool->clock_sources[i]);
-+ }
-+ return false;
-+}
-+
-+void dce110_destruct_resource_pool(struct resource_pool *pool)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < pool->controller_count; i++) {
-+ if (pool->opps[i] != NULL)
-+ dce110_opp_destroy(&pool->opps[i]);
-+
-+ if (pool->transforms[i] != NULL)
-+ dce110_transform_destroy(&pool->transforms[i]);
-+
-+ if (pool->ipps[i] != NULL)
-+ dce110_ipp_destroy(&pool->ipps[i]);
-+
-+ if (pool->mis[i] != NULL)
-+ dce110_mem_input_destroy(&pool->mis[i]);
-+
-+ if (pool->timing_generators[i] != NULL)
-+ dce110_timing_generator_destroy(
-+ &pool->timing_generators[i]);
-+ }
-+
-+ for (i = 0; i < pool->stream_enc_count; i++) {
-+ if (pool->stream_enc[i] != NULL)
-+ dce110_stream_encoder_destroy(&pool->stream_enc[i]);
-+ }
-+
-+ for (i = 0; i < pool->clk_src_count; i++) {
-+ if (pool->clock_sources[i] != NULL) {
-+ dal_clock_source_destroy(&pool->clock_sources[i]);
-+ }
-+ }
-+
-+ for (i = 0; i < pool->audio_count; i++) {
-+ if (pool->audios[i] != NULL) {
-+ dal_audio_destroy(&pool->audios[i]);
-+ }
-+ }
-+ if (pool->display_clock != NULL) {
-+ dal_display_clock_destroy(&pool->display_clock);
-+ }
-+
-+ if (pool->scaler_filter != NULL) {
-+ dal_scaler_filter_destroy(&pool->scaler_filter);
-+ }
-+ if (pool->irqs != NULL) {
-+ dal_irq_service_destroy(&pool->irqs);
-+ }
-+
-+ if (pool->adapter_srv != NULL) {
-+ dal_adapter_service_destroy(&pool->adapter_srv);
-+ }
-+}
-+
-+static void attach_stream_to_controller(
-+ struct resource_context *res_ctx,
-+ struct core_stream *stream)
-+{
-+ res_ctx->controller_ctx[stream->controller_idx].stream = stream;
-+}
-+
-+static bool assign_first_free_controller(
-+ struct resource_context *res_ctx,
-+ struct core_stream *stream)
-+{
-+ uint8_t i;
-+ for (i = 0; i < res_ctx->pool.controller_count; i++) {
-+ if (!res_ctx->controller_ctx[i].stream) {
-+ stream->tg = res_ctx->pool.timing_generators[i];
-+ stream->mi = res_ctx->pool.mis[i];
-+ stream->ipp = res_ctx->pool.ipps[i];
-+ stream->xfm = res_ctx->pool.transforms[i];
-+ stream->opp = res_ctx->pool.opps[i];
-+ stream->controller_idx = i;
-+ stream->dis_clk = res_ctx->pool.display_clock;
-+ return true;
-+ }
-+ }
-+ return false;
-+}
-+
-+static void set_stream_engine_in_use(
-+ struct resource_context *res_ctx,
-+ struct stream_encoder *stream_enc)
-+{
-+ int i;
-+
-+ for (i = 0; i < res_ctx->pool.stream_enc_count; i++) {
-+ if (res_ctx->pool.stream_enc[i] == stream_enc)
-+ res_ctx->is_stream_enc_acquired[i] = true;
-+ }
-+}
-+
-+static struct stream_encoder *find_first_free_match_stream_enc_for_link(
-+ struct resource_context *res_ctx,
-+ struct core_link *link)
-+{
-+ uint8_t i;
-+
-+ for (i = 0; i < res_ctx->pool.stream_enc_count; i++) {
-+ if (!res_ctx->is_stream_enc_acquired[i] &&
-+ res_ctx->pool.stream_enc[i]) {
-+ if (res_ctx->pool.stream_enc[i]->id ==
-+ link->link_enc->preferred_engine)
-+ return res_ctx->pool.stream_enc[i];
-+ }
-+ }
-+
-+ /* TODO: Handle MST*/
-+
-+ return NULL;
-+}
-+
-+/* TODO: release audio object */
-+static void set_audio_in_use(
-+ struct resource_context *res_ctx,
-+ struct audio *audio)
-+{
-+ int i;
-+ for (i = 0; i < res_ctx->pool.audio_count; i++) {
-+ if (res_ctx->pool.audios[i] == audio) {
-+ res_ctx->is_audio_acquired[i] = true;
-+ }
-+ }
-+}
-+
-+static struct audio *find_first_free_audio(struct resource_context *res_ctx)
-+{
-+ int i;
-+ for (i = 0; i < res_ctx->pool.audio_count; i++) {
-+ if (res_ctx->is_audio_acquired[i] == false) {
-+ return res_ctx->pool.audios[i];
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static struct clock_source *find_first_free_pll(
-+ struct resource_context *res_ctx)
-+{
-+ if (res_ctx->clock_source_ref_count[DCE110_CLK_SRC_PLL0] == 0) {
-+ return res_ctx->pool.clock_sources[DCE110_CLK_SRC_PLL0];
-+ }
-+ if (res_ctx->clock_source_ref_count[DCE110_CLK_SRC_PLL1] == 0) {
-+ return res_ctx->pool.clock_sources[DCE110_CLK_SRC_PLL1];
-+ }
-+
-+ return 0;
-+}
-+
-+static bool check_timing_change(struct core_stream *cur_stream,
-+ struct core_stream *new_stream)
-+{
-+ if (cur_stream == NULL)
-+ return true;
-+
-+ /* If sink pointer changed, it means this is a hotplug, we should do
-+ * full hw setting.
-+ */
-+ if (cur_stream->sink != new_stream->sink)
-+ return true;
-+
-+ return !is_same_timing(
-+ &cur_stream->public.timing,
-+ &new_stream->public.timing);
-+}
-+
-+static enum dc_status map_resources(
-+ const struct dc *dc,
-+ struct validate_context *context)
-+{
-+ uint8_t i, j;
-+
-+ /* mark resources used for targets that are already active */
-+ for (i = 0; i < context->target_count; i++) {
-+ struct core_target *target = context->targets[i];
-+ if (context->target_flags[i].unchanged)
-+ for (j = 0; j < target->stream_count; j++) {
-+ struct core_stream *stream = target->streams[j];
-+ attach_stream_to_controller(
-+ &context->res_ctx,
-+ stream);
-+
-+ set_stream_engine_in_use(
-+ &context->res_ctx,
-+ stream->stream_enc);
-+
-+ reference_clock_source(
-+ &context->res_ctx,
-+ stream->clock_source);
-+
-+ if (stream->audio) {
-+ set_audio_in_use(&context->res_ctx,
-+ stream->audio);
-+ }
-+ }
-+ }
-+
-+ /* acquire new resources */
-+ for (i = 0; i < context->target_count; i++) {
-+ struct core_target *target = context->targets[i];
-+ if (context->target_flags[i].unchanged)
-+ continue;
-+ for (j = 0; j < target->stream_count; j++) {
-+ struct core_stream *stream = target->streams[j];
-+ struct core_stream *curr_stream;
-+
-+ if (!assign_first_free_controller(
-+ &context->res_ctx, stream))
-+ return DC_NO_CONTROLLER_RESOURCE;
-+
-+ attach_stream_to_controller(&context->res_ctx, stream);
-+
-+ stream->stream_enc =
-+ find_first_free_match_stream_enc_for_link(
-+ &context->res_ctx,
-+ stream->sink->link);
-+
-+ if (!stream->stream_enc)
-+ return DC_NO_STREAM_ENG_RESOURCE;
-+
-+ set_stream_engine_in_use(
-+ &context->res_ctx,
-+ stream->stream_enc);
-+ stream->signal =
-+ stream->sink->public.sink_signal;
-+
-+ if (dc_is_dp_signal(stream->signal))
-+ stream->clock_source = context->res_ctx.
-+ pool.clock_sources[DCE110_CLK_SRC_EXT];
-+ else
-+ stream->clock_source =
-+ find_used_clk_src_for_sharing(
-+ context, stream);
-+ if (stream->clock_source == NULL)
-+ stream->clock_source =
-+ find_first_free_pll(&context->res_ctx);
-+
-+ if (stream->clock_source == NULL)
-+ return DC_NO_CLOCK_SOURCE_RESOURCE;
-+
-+ reference_clock_source(
-+ &context->res_ctx,
-+ stream->clock_source);
-+
-+ /* TODO: Add check if ASIC support and EDID audio */
-+ if (!stream->sink->converter_disable_audio &&
-+ dc_is_audio_capable_signal(
-+ stream->signal)) {
-+ stream->audio = find_first_free_audio(
-+ &context->res_ctx);
-+
-+ if (!stream->audio)
-+ return DC_NO_STREAM_AUDIO_RESOURCE;
-+
-+ set_audio_in_use(&context->res_ctx,
-+ stream->audio);
-+ }
-+ curr_stream =
-+ dc->current_context.res_ctx.controller_ctx
-+ [stream->controller_idx].stream;
-+ context->res_ctx.controller_ctx[stream->controller_idx]
-+ .flags.timing_changed =
-+ check_timing_change(curr_stream, stream);
-+
-+ }
-+ }
-+
-+ return DC_OK;
-+}
-+
-+static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id)
-+{
-+ switch (crtc_id) {
-+ case CONTROLLER_ID_D0:
-+ return DTO_SOURCE_ID0;
-+ case CONTROLLER_ID_D1:
-+ return DTO_SOURCE_ID1;
-+ case CONTROLLER_ID_D2:
-+ return DTO_SOURCE_ID2;
-+ case CONTROLLER_ID_D3:
-+ return DTO_SOURCE_ID3;
-+ case CONTROLLER_ID_D4:
-+ return DTO_SOURCE_ID4;
-+ case CONTROLLER_ID_D5:
-+ return DTO_SOURCE_ID5;
-+ default:
-+ return DTO_SOURCE_UNKNOWN;
-+ }
-+}
-+
-+static void build_audio_output(
-+ const struct core_stream *stream,
-+ struct audio_output *audio_output)
-+{
-+ audio_output->engine_id = stream->stream_enc->id;
-+
-+ audio_output->signal = stream->signal;
-+
-+ /* audio_crtc_info */
-+
-+ audio_output->crtc_info.h_total =
-+ stream->public.timing.h_total;
-+
-+ /* Audio packets are sent during actual CRTC blank physical signal, we
-+ * need to specify actual active signal portion */
-+ audio_output->crtc_info.h_active =
-+ stream->public.timing.h_addressable
-+ + stream->public.timing.h_border_left
-+ + stream->public.timing.h_border_right;
-+
-+ audio_output->crtc_info.v_active =
-+ stream->public.timing.v_addressable
-+ + stream->public.timing.v_border_top
-+ + stream->public.timing.v_border_bottom;
-+
-+ audio_output->crtc_info.pixel_repetition = 1;
-+
-+ audio_output->crtc_info.interlaced =
-+ stream->public.timing.flags.INTERLACE;
-+
-+ audio_output->crtc_info.refresh_rate =
-+ (stream->public.timing.pix_clk_khz*1000)/
-+ (stream->public.timing.h_total*stream->public.timing.v_total);
-+
-+ audio_output->crtc_info.color_depth =
-+ stream->public.timing.display_color_depth;
-+
-+ audio_output->crtc_info.requested_pixel_clock =
-+ stream->pix_clk_params.requested_pix_clk;
-+
-+ /* TODO - Investigate why calculated pixel clk has to be
-+ * requested pixel clk */
-+ audio_output->crtc_info.calculated_pixel_clock =
-+ stream->pix_clk_params.requested_pix_clk;
-+
-+ /* TODO: This is needed for DP */
-+ if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT) {
-+ audio_output->pll_info.dp_dto_source_clock_in_khz =
-+ dal_display_clock_get_dp_ref_clk_frequency(
-+ stream->dis_clk);
-+ }
-+
-+ audio_output->pll_info.feed_back_divider =
-+ stream->pll_settings.feedback_divider;
-+
-+ audio_output->pll_info.dto_source =
-+ translate_to_dto_source(
-+ stream->controller_idx + 1);
-+
-+ /* TODO hard code to enable for now. Need get from stream */
-+ audio_output->pll_info.ss_enabled = true;
-+
-+ audio_output->pll_info.ss_percentage =
-+ stream->pll_settings.ss_percentage;
-+}
-+
-+static void get_pixel_clock_parameters(
-+ const struct core_stream *stream,
-+ struct pixel_clk_params *pixel_clk_params)
-+{
-+ pixel_clk_params->requested_pix_clk = stream->public.timing.pix_clk_khz;
-+ pixel_clk_params->encoder_object_id = stream->sink->link->link_enc->id;
-+ pixel_clk_params->signal_type = stream->sink->public.sink_signal;
-+ pixel_clk_params->controller_id = stream->controller_idx + 1;
-+ /* TODO: un-hardcode*/
-+ pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
-+ LINK_RATE_REF_FREQ_IN_KHZ;
-+ pixel_clk_params->flags.ENABLE_SS = 0;
-+ pixel_clk_params->color_depth =
-+ stream->public.timing.display_color_depth;
-+ pixel_clk_params->flags.DISPLAY_BLANKED = 1;
-+}
-+
-+static enum dc_status build_stream_hw_param(struct core_stream *stream)
-+{
-+ /*TODO: unhardcode*/
-+ stream->max_tmds_clk_from_edid_in_mhz = 0;
-+ stream->max_hdmi_deep_color = COLOR_DEPTH_121212;
-+ stream->max_hdmi_pixel_clock = 600000;
-+
-+ get_pixel_clock_parameters(stream, &stream->pix_clk_params);
-+ dal_clock_source_get_pix_clk_dividers(
-+ stream->clock_source,
-+ &stream->pix_clk_params,
-+ &stream->pll_settings);
-+
-+ build_audio_output(stream, &stream->audio_output);
-+
-+ return DC_OK;
-+}
-+
-+static enum dc_status validate_mapped_resource(
-+ const struct dc *dc,
-+ struct validate_context *context)
-+{
-+ enum dc_status status = DC_OK;
-+ uint8_t i, j;
-+
-+ for (i = 0; i < context->target_count; i++) {
-+ struct core_target *target = context->targets[i];
-+ if (context->target_flags[i].unchanged)
-+ continue;
-+ for (j = 0; j < target->stream_count; j++) {
-+ struct core_stream *stream = target->streams[j];
-+ struct core_link *link = stream->sink->link;
-+ status = build_stream_hw_param(stream);
-+
-+ if (status != DC_OK)
-+ return status;
-+
-+ if (!dce110_timing_generator_validate_timing(
-+ stream->tg,
-+ &stream->public.timing,
-+ SIGNAL_TYPE_HDMI_TYPE_A))
-+ return DC_FAIL_CONTROLLER_VALIDATE;
-+
-+
-+ if (dce110_link_encoder_validate_output_with_stream(
-+ link->link_enc,
-+ stream)
-+ != ENCODER_RESULT_OK)
-+ return DC_FAIL_ENC_VALIDATE;
-+
-+ /* TODO: validate audio ASIC caps, encoder */
-+
-+ status = dc_link_validate_mode_timing(stream->sink,
-+ link,
-+ &stream->public.timing);
-+
-+ if (status != DC_OK)
-+ return status;
-+
-+ build_info_frame(stream);
-+ }
-+ }
-+
-+ return DC_OK;
-+}
-+
-+enum dc_status dce110_validate_bandwidth(
-+ const struct dc *dc,
-+ struct validate_context *context)
-+{
-+ uint8_t i, j;
-+ enum dc_status result = DC_ERROR_UNEXPECTED;
-+ uint8_t number_of_displays = 0;
-+
-+ memset(&context->bw_mode_data, 0, sizeof(context->bw_mode_data));
-+
-+ for (i = 0; i < context->target_count; i++) {
-+ struct core_target *target = context->targets[i];
-+ for (j = 0; j < target->stream_count; j++) {
-+ struct core_stream *stream = target->streams[j];
-+ struct bw_calcs_input_single_display *disp = &context->
-+ bw_mode_data.displays_data[number_of_displays];
-+
-+ if (target->status.surface_count == 0) {
-+ disp->graphics_scale_ratio = int_to_fixed(1);
-+ disp->graphics_h_taps = 4;
-+ disp->graphics_v_taps = 4;
-+
-+ } else {
-+ disp->graphics_scale_ratio =
-+ fixed31_32_to_bw_fixed(
-+ stream->ratios.vert.value);
-+ disp->graphics_h_taps = stream->taps.h_taps;
-+ disp->graphics_v_taps = stream->taps.v_taps;
-+ }
-+
-+ disp->graphics_src_width =
-+ stream->public.timing.h_addressable;
-+ disp->graphics_src_height =
-+ stream->public.timing.v_addressable;
-+ disp->h_total = stream->public.timing.h_total;
-+ disp->pixel_rate = frc_to_fixed(
-+ stream->public.timing.pix_clk_khz, 1000);
-+
-+ /*TODO: get from surface*/
-+ disp->graphics_bytes_per_pixel = 4;
-+ disp->graphics_tiling_mode = tiled;
-+
-+ /* DCE11 defaults*/
-+ disp->graphics_lb_bpc = 10;
-+ disp->graphics_interlace_mode = false;
-+ disp->fbc_enable = false;
-+ disp->lpt_enable = false;
-+ disp->graphics_stereo_mode = mono;
-+ disp->underlay_mode = ul_none;
-+
-+ number_of_displays++;
-+ }
-+ }
-+
-+ context->bw_mode_data.number_of_displays = number_of_displays;
-+ context->bw_mode_data.display_synchronization_enabled = false;
-+
-+ dal_logger_write(dc->ctx->logger,
-+ LOG_MAJOR_BWM,
-+ LOG_MINOR_BWM_REQUIRED_BANDWIDTH_CALCS,
-+ "%s: Start bandwidth calculations",
-+ __func__);
-+ if (true == bw_calcs(
-+ dc->ctx,
-+ &dc->bw_dceip,
-+ &dc->bw_vbios,
-+ &context->bw_mode_data,
-+ &context->bw_results))
-+ result = DC_OK;
-+ else {
-+ result = DC_FAIL_BANDWIDTH_VALIDATE;
-+ dal_logger_write(dc->ctx->logger,
-+ LOG_MAJOR_BWM,
-+ LOG_MINOR_BWM_MODE_VALIDATION,
-+ "%s: Bandwidth validation failed!",
-+ __func__);
-+ }
-+
-+
-+ dal_logger_write(dc->ctx->logger,
-+ LOG_MAJOR_BWM,
-+ LOG_MINOR_BWM_REQUIRED_BANDWIDTH_CALCS,
-+ "%s: Finish bandwidth calculations\n nbpMark: %d",
-+ __func__,
-+ context->bw_results.nbp_state_change_watermark[0].b_mark);
-+
-+ return result;
-+}
-+
-+static void set_target_unchanged(
-+ struct validate_context *context,
-+ uint8_t target_idx)
-+{
-+ uint8_t i;
-+ struct core_target *target = context->targets[target_idx];
-+ context->target_flags[target_idx].unchanged = true;
-+ for (i = 0; i < target->stream_count; i++) {
-+ uint8_t index = target->streams[i]->controller_idx;
-+ context->res_ctx.controller_ctx[index].flags.unchanged = true;
-+ }
-+}
-+
-+enum dc_status dce110_validate_with_context(
-+ const struct dc *dc,
-+ const struct dc_validation_set set[],
-+ uint8_t set_count,
-+ struct validate_context *context)
-+{
-+ enum dc_status result = DC_ERROR_UNEXPECTED;
-+ uint8_t i, j;
-+ struct dc_context *dc_ctx = dc->ctx;
-+
-+ for (i = 0; i < set_count; i++) {
-+ context->targets[i] = DC_TARGET_TO_CORE(set[i].target);
-+
-+ for (j = 0; j < dc->current_context.target_count; j++)
-+ if (dc->current_context.targets[j] == context->targets[i])
-+ set_target_unchanged(context, i);
-+
-+ if (!context->target_flags[i].unchanged)
-+ if (!logical_attach_surfaces_to_target(
-+ (struct dc_surface **)set[i].surfaces,
-+ set[i].surface_count,
-+ &context->targets[i]->public)) {
-+ DC_ERROR("Failed to attach surface to target!\n");
-+ return DC_FAIL_ATTACH_SURFACES;
-+ }
-+ }
-+
-+ context->target_count = set_count;
-+
-+ context->res_ctx.pool = dc->res_pool;
-+
-+ result = map_resources(dc, context);
-+
-+ if (result == DC_OK)
-+ result = validate_mapped_resource(dc, context);
-+
-+ if (result == DC_OK)
-+ build_scaling_params_for_context(dc, context);
-+
-+ if (result == DC_OK)
-+ result = dce110_validate_bandwidth(dc, context);
-+
-+ return result;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.h
-new file mode 100644
-index 0000000..e113d11
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.h
-@@ -0,0 +1,55 @@
-+/*
-+* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_RESOURCE_DCE110_H__
-+#define __DC_RESOURCE_DCE110_H__
-+
-+#include "core_types.h"
-+
-+struct adapter_service;
-+struct dc;
-+struct resource_pool;
-+struct dc_validation_set;
-+
-+
-+bool dce110_construct_resource_pool(
-+ struct adapter_service *adapter_serv,
-+ struct dc *dc,
-+ struct resource_pool *pool);
-+
-+void dce110_destruct_resource_pool(struct resource_pool *pool);
-+
-+enum dc_status dce110_validate_with_context(
-+ const struct dc *dc,
-+ const struct dc_validation_set set[],
-+ uint8_t set_count,
-+ struct validate_context *context);
-+
-+enum dc_status dce110_validate_bandwidth(
-+ const struct dc *dc,
-+ struct validate_context *context);
-+
-+#endif /* __DC_RESOURCE_DCE110_H__ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.c
-new file mode 100644
-index 0000000..a9edf96
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.c
-@@ -0,0 +1,1168 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "stream_encoder_types.h"
-+#include "dce110_stream_encoder.h"
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+#include "dce/dce_11_0_enum.h"
-+
-+static const uint32_t fe_engine_offsets[] = {
-+ mmDIG0_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+ mmDIG1_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+ mmDIG2_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+};
-+
-+#define VBI_LINE_0 0
-+#define DP_BLANK_MAX_RETRY 20
-+#define HDMI_CLOCK_CHANNEL_RATE_MORE_340M 340000
-+
-+#ifndef HDMI_CONTROL__HDMI_DATA_SCRAMBLE_EN_MASK
-+ #define HDMI_CONTROL__HDMI_DATA_SCRAMBLE_EN_MASK 0x2
-+ #define HDMI_CONTROL__HDMI_DATA_SCRAMBLE_EN__SHIFT 0x1
-+#endif
-+
-+static void construct(
-+ struct stream_encoder *enc,
-+ struct stream_enc_init_data *init)
-+{
-+ enc->ctx = init->ctx;
-+ enc->id = init->stream_engine_id;
-+ enc->adapter_service = init->adapter_service;
-+}
-+
-+struct stream_encoder *dce110_stream_encoder_create(
-+ struct stream_enc_init_data *init)
-+{
-+ struct stream_encoder *enc =
-+ dc_service_alloc(init->ctx, sizeof(struct stream_encoder));
-+
-+ if (!enc)
-+ goto enc_create_fail;
-+
-+ construct(enc, init);
-+
-+ return enc;
-+
-+enc_create_fail:
-+ return NULL;
-+}
-+
-+void dce110_stream_encoder_destroy(struct stream_encoder **enc)
-+{
-+ dc_service_free((*enc)->ctx, *enc);
-+ *enc = NULL;
-+}
-+
-+static void stop_hdmi_info_packets(struct dc_context *ctx, uint32_t offset)
-+{
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+
-+ /* stop generic packets 0 & 1 on HDMI */
-+ addr = mmHDMI_GENERIC_PACKET_CONTROL0 + offset;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_GENERIC_PACKET_CONTROL0,
-+ HDMI_GENERIC1_CONT);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_GENERIC_PACKET_CONTROL0,
-+ HDMI_GENERIC1_LINE);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_GENERIC_PACKET_CONTROL0,
-+ HDMI_GENERIC1_SEND);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_GENERIC_PACKET_CONTROL0,
-+ HDMI_GENERIC0_CONT);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_GENERIC_PACKET_CONTROL0,
-+ HDMI_GENERIC0_LINE);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_GENERIC_PACKET_CONTROL0,
-+ HDMI_GENERIC0_SEND);
-+
-+ dal_write_reg(ctx, addr, value);
-+
-+ /* stop generic packets 2 & 3 on HDMI */
-+ addr = mmHDMI_GENERIC_PACKET_CONTROL1 + offset;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_GENERIC_PACKET_CONTROL1,
-+ HDMI_GENERIC2_CONT);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_GENERIC_PACKET_CONTROL1,
-+ HDMI_GENERIC2_LINE);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_GENERIC_PACKET_CONTROL1,
-+ HDMI_GENERIC2_SEND);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_GENERIC_PACKET_CONTROL1,
-+ HDMI_GENERIC3_CONT);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_GENERIC_PACKET_CONTROL1,
-+ HDMI_GENERIC3_LINE);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_GENERIC_PACKET_CONTROL1,
-+ HDMI_GENERIC3_SEND);
-+
-+ dal_write_reg(ctx, addr, value);
-+
-+ /* stop AVI packet on HDMI */
-+ addr = mmHDMI_INFOFRAME_CONTROL0 + offset;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_INFOFRAME_CONTROL0,
-+ HDMI_AVI_INFO_SEND);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_INFOFRAME_CONTROL0,
-+ HDMI_AVI_INFO_CONT);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+static void stop_dp_info_packets(struct dc_context *ctx, int32_t offset)
-+{
-+ /* stop generic packets on DP */
-+
-+ const uint32_t addr = mmDP_SEC_CNTL + offset;
-+
-+ uint32_t value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP0_ENABLE);
-+ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP1_ENABLE);
-+ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP2_ENABLE);
-+ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_GSP3_ENABLE);
-+ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_AVI_ENABLE);
-+ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_MPG_ENABLE);
-+ set_reg_field_value(value, 0, DP_SEC_CNTL, DP_SEC_STREAM_ENABLE);
-+
-+ /* this register shared with audio info frame.
-+ * therefore we need to keep master enabled
-+ * if at least one of the fields is not 0 */
-+
-+ if (value)
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DP_SEC_CNTL,
-+ DP_SEC_STREAM_ENABLE);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+void dce110_stream_encoder_stop_info_packets(
-+ struct stream_encoder *enc,
-+ enum engine_id engine,
-+ enum signal_type signal)
-+{
-+ if (dc_is_hdmi_signal(signal))
-+ stop_hdmi_info_packets(
-+ enc->ctx,
-+ fe_engine_offsets[engine]);
-+ else if (dc_is_dp_signal(signal))
-+ stop_dp_info_packets(
-+ enc->ctx,
-+ fe_engine_offsets[engine]);
-+}
-+
-+
-+static void update_avi_info_packet(
-+ struct stream_encoder *enc,
-+ enum engine_id engine,
-+ enum signal_type signal,
-+ const struct encoder_info_packet *info_packet)
-+{
-+ const int32_t offset = fe_engine_offsets[engine];
-+
-+ uint32_t regval;
-+ uint32_t addr;
-+
-+ if (info_packet->valid) {
-+ const uint32_t *content =
-+ (const uint32_t *) &info_packet->sb[0];
-+
-+ {
-+ regval = content[0];
-+
-+ dal_write_reg(
-+ enc->ctx,
-+ mmAFMT_AVI_INFO0 + offset,
-+ regval);
-+ }
-+ {
-+ regval = content[1];
-+
-+ dal_write_reg(
-+ enc->ctx,
-+ mmAFMT_AVI_INFO1 + offset,
-+ regval);
-+ }
-+ {
-+ regval = content[2];
-+
-+ dal_write_reg(
-+ enc->ctx,
-+ mmAFMT_AVI_INFO2 + offset,
-+ regval);
-+ }
-+ {
-+ regval = content[3];
-+
-+ /* move version to AVI_INFO3 */
-+ set_reg_field_value(
-+ regval,
-+ info_packet->hb1,
-+ AFMT_AVI_INFO3,
-+ AFMT_AVI_INFO_VERSION);
-+
-+ dal_write_reg(
-+ enc->ctx,
-+ mmAFMT_AVI_INFO3 + offset,
-+ regval);
-+ }
-+
-+ if (dc_is_hdmi_signal(signal)) {
-+
-+ uint32_t control0val;
-+ uint32_t control1val;
-+
-+ addr = mmHDMI_INFOFRAME_CONTROL0 + offset;
-+
-+ control0val = dal_read_reg(enc->ctx, addr);
-+
-+ set_reg_field_value(
-+ control0val,
-+ 1,
-+ HDMI_INFOFRAME_CONTROL0,
-+ HDMI_AVI_INFO_SEND);
-+
-+ set_reg_field_value(
-+ control0val,
-+ 1,
-+ HDMI_INFOFRAME_CONTROL0,
-+ HDMI_AVI_INFO_CONT);
-+
-+ dal_write_reg(enc->ctx, addr, control0val);
-+
-+ addr = mmHDMI_INFOFRAME_CONTROL1 + offset;
-+
-+ control1val = dal_read_reg(enc->ctx, addr);
-+
-+ set_reg_field_value(
-+ control1val,
-+ VBI_LINE_0 + 2,
-+ HDMI_INFOFRAME_CONTROL1,
-+ HDMI_AVI_INFO_LINE);
-+
-+ dal_write_reg(enc->ctx, addr, control1val);
-+ }
-+ } else if (dc_is_hdmi_signal(signal)) {
-+ addr = mmHDMI_INFOFRAME_CONTROL0 + offset;
-+
-+ regval = dal_read_reg(enc->ctx, addr);
-+
-+ set_reg_field_value(
-+ regval,
-+ 0,
-+ HDMI_INFOFRAME_CONTROL0,
-+ HDMI_AVI_INFO_SEND);
-+
-+ set_reg_field_value(
-+ regval,
-+ 0,
-+ HDMI_INFOFRAME_CONTROL0,
-+ HDMI_AVI_INFO_CONT);
-+
-+ dal_write_reg(enc->ctx, addr, regval);
-+ }
-+}
-+
-+static void update_generic_info_packet(
-+ struct stream_encoder *enc,
-+ enum engine_id engine,
-+ uint32_t packet_index,
-+ const struct encoder_info_packet *info_packet)
-+{
-+ uint32_t addr;
-+ uint32_t regval;
-+ /* choose which generic packet to use */
-+ {
-+ addr = mmAFMT_VBI_PACKET_CONTROL + fe_engine_offsets[engine];
-+
-+ regval = dal_read_reg(enc->ctx, addr);
-+
-+ set_reg_field_value(
-+ regval,
-+ packet_index,
-+ AFMT_VBI_PACKET_CONTROL,
-+ AFMT_GENERIC_INDEX);
-+
-+ dal_write_reg(enc->ctx, addr, regval);
-+ }
-+
-+ /* write generic packet header
-+ * (4th byte is for GENERIC0 only) */
-+ {
-+ addr = mmAFMT_GENERIC_HDR + fe_engine_offsets[engine];
-+
-+ regval = 0;
-+
-+ set_reg_field_value(
-+ regval,
-+ info_packet->hb0,
-+ AFMT_GENERIC_HDR,
-+ AFMT_GENERIC_HB0);
-+
-+ set_reg_field_value(
-+ regval,
-+ info_packet->hb1,
-+ AFMT_GENERIC_HDR,
-+ AFMT_GENERIC_HB1);
-+
-+ set_reg_field_value(
-+ regval,
-+ info_packet->hb2,
-+ AFMT_GENERIC_HDR,
-+ AFMT_GENERIC_HB2);
-+
-+ set_reg_field_value(
-+ regval,
-+ info_packet->hb3,
-+ AFMT_GENERIC_HDR,
-+ AFMT_GENERIC_HB3);
-+
-+ dal_write_reg(enc->ctx, addr, regval);
-+ }
-+
-+ /* write generic packet contents
-+ * (we never use last 4 bytes)
-+ * there are 8 (0-7) mmDIG0_AFMT_GENERIC0_x registers */
-+ {
-+ const uint32_t *content =
-+ (const uint32_t *) &info_packet->sb[0];
-+
-+ uint32_t counter = 0;
-+
-+ addr = mmAFMT_GENERIC_0 + fe_engine_offsets[engine];
-+
-+ do {
-+ dal_write_reg(enc->ctx, addr++, *content++);
-+
-+ ++counter;
-+ } while (counter < 7);
-+ }
-+
-+ dal_write_reg(
-+ enc->ctx,
-+ mmAFMT_GENERIC_7 + fe_engine_offsets[engine],
-+ 0);
-+
-+ /* force double-buffered packet update */
-+ {
-+ addr = mmAFMT_VBI_PACKET_CONTROL + fe_engine_offsets[engine];
-+
-+ regval = dal_read_reg(enc->ctx, addr);
-+
-+ set_reg_field_value(
-+ regval,
-+ (packet_index == 0),
-+ AFMT_VBI_PACKET_CONTROL,
-+ AFMT_GENERIC0_UPDATE);
-+
-+ set_reg_field_value(
-+ regval,
-+ (packet_index == 2),
-+ AFMT_VBI_PACKET_CONTROL,
-+ AFMT_GENERIC2_UPDATE);
-+
-+ dal_write_reg(enc->ctx, addr, regval);
-+ }
-+}
-+
-+static void update_hdmi_info_packet(
-+ struct stream_encoder *enc,
-+ enum engine_id engine,
-+ uint32_t packet_index,
-+ const struct encoder_info_packet *info_packet)
-+{
-+ uint32_t cont, send, line;
-+ uint32_t addr = fe_engine_offsets[engine];
-+ uint32_t regval;
-+
-+ if (info_packet->valid) {
-+ update_generic_info_packet(
-+ enc,
-+ engine,
-+ packet_index,
-+ info_packet);
-+
-+ /* enable transmission of packet(s) -
-+ * packet transmission begins on the next frame */
-+ cont = 1;
-+ /* send packet(s) every frame */
-+ send = 1;
-+ /* select line number to send packets on */
-+ line = 2;
-+ } else {
-+ cont = 0;
-+ send = 0;
-+ line = 0;
-+ }
-+
-+ /* choose which generic packet control to use */
-+
-+ switch (packet_index) {
-+ case 0:
-+ case 1:
-+ addr += mmHDMI_GENERIC_PACKET_CONTROL0;
-+ break;
-+ case 2:
-+ case 3:
-+ addr += mmHDMI_GENERIC_PACKET_CONTROL1;
-+ break;
-+ default:
-+ /* invalid HW packet index */
-+ dal_logger_write(
-+ enc->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_ENCODER,
-+ "Invalid HW packet index: %s()\n",
-+ __func__);
-+ break;
-+ }
-+
-+ regval = dal_read_reg(enc->ctx, addr);
-+
-+ switch (packet_index) {
-+ case 0:
-+ case 2:
-+ set_reg_field_value(
-+ regval,
-+ cont,
-+ HDMI_GENERIC_PACKET_CONTROL0,
-+ HDMI_GENERIC0_CONT);
-+ set_reg_field_value(
-+ regval,
-+ send,
-+ HDMI_GENERIC_PACKET_CONTROL0,
-+ HDMI_GENERIC0_SEND);
-+ set_reg_field_value(
-+ regval,
-+ line,
-+ HDMI_GENERIC_PACKET_CONTROL0,
-+ HDMI_GENERIC0_LINE);
-+ break;
-+ case 1:
-+ case 3:
-+ set_reg_field_value(
-+ regval,
-+ cont,
-+ HDMI_GENERIC_PACKET_CONTROL0,
-+ HDMI_GENERIC1_CONT);
-+ set_reg_field_value(
-+ regval,
-+ send,
-+ HDMI_GENERIC_PACKET_CONTROL0,
-+ HDMI_GENERIC1_SEND);
-+ set_reg_field_value(
-+ regval,
-+ line,
-+ HDMI_GENERIC_PACKET_CONTROL0,
-+ HDMI_GENERIC1_LINE);
-+ break;
-+ default:
-+ /* invalid HW packet index */
-+ dal_logger_write(
-+ enc->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_ENCODER,
-+ "Invalid HW packet index: %s()\n",
-+ __func__);
-+ break;
-+ }
-+
-+ dal_write_reg(enc->ctx, addr, regval);
-+}
-+
-+static void update_dp_info_packet(
-+ struct stream_encoder *enc,
-+ enum engine_id engine,
-+ uint32_t packet_index,
-+ const struct encoder_info_packet *info_packet)
-+{
-+ const uint32_t addr = mmDP_SEC_CNTL + fe_engine_offsets[engine];
-+
-+ uint32_t value;
-+
-+ if (info_packet->valid)
-+ update_generic_info_packet(
-+ enc,
-+ engine,
-+ packet_index,
-+ info_packet);
-+
-+ /* enable/disable transmission of packet(s).
-+ * If enabled, packet transmission begins on the next frame */
-+
-+ value = dal_read_reg(enc->ctx, addr);
-+
-+ switch (packet_index) {
-+ case 0:
-+ set_reg_field_value(
-+ value,
-+ info_packet->valid,
-+ DP_SEC_CNTL,
-+ DP_SEC_GSP0_ENABLE);
-+ break;
-+ case 1:
-+ set_reg_field_value(
-+ value,
-+ info_packet->valid,
-+ DP_SEC_CNTL,
-+ DP_SEC_GSP1_ENABLE);
-+ break;
-+ case 2:
-+ set_reg_field_value(
-+ value,
-+ info_packet->valid,
-+ DP_SEC_CNTL,
-+ DP_SEC_GSP2_ENABLE);
-+ break;
-+ case 3:
-+ set_reg_field_value(
-+ value,
-+ info_packet->valid,
-+ DP_SEC_CNTL,
-+ DP_SEC_GSP3_ENABLE);
-+ break;
-+ default:
-+ /* invalid HW packet index */
-+ ASSERT_CRITICAL(false);
-+ return;
-+ }
-+
-+ /* This bit is the master enable bit.
-+ * When enabling secondary stream engine,
-+ * this master bit must also be set.
-+ * This register shared with audio info frame.
-+ * Therefore we need to enable master bit
-+ * if at least on of the fields is not 0 */
-+
-+ if (value)
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DP_SEC_CNTL,
-+ DP_SEC_STREAM_ENABLE);
-+
-+ dal_write_reg(enc->ctx, addr, value);
-+}
-+
-+void dce110_stream_encoder_update_info_packets(
-+ struct stream_encoder *enc,
-+ enum signal_type signal,
-+ const struct encoder_info_frame *info_frame)
-+{
-+ if (dc_is_hdmi_signal(signal)) {
-+ update_avi_info_packet(
-+ enc,
-+ enc->id,
-+ signal,
-+ &info_frame->avi);
-+ update_hdmi_info_packet(enc, enc->id, 0, &info_frame->vendor);
-+ update_hdmi_info_packet(enc, enc->id, 1, &info_frame->gamut);
-+ update_hdmi_info_packet(enc, enc->id, 2, &info_frame->spd);
-+ } else if (dc_is_dp_signal(signal))
-+ update_dp_info_packet(enc, enc->id, 0, &info_frame->vsc);
-+}
-+
-+static void dp_steer_fifo_reset(
-+ struct dc_context *ctx,
-+ enum engine_id engine,
-+ bool reset)
-+{
-+ const uint32_t addr = mmDP_STEER_FIFO + fe_engine_offsets[engine];
-+
-+ uint32_t value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(value, reset, DP_STEER_FIFO, DP_STEER_FIFO_RESET);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+/*
-+ * @brief
-+ * Output blank data,
-+ * prevents output of the actual surface data on active transmitter
-+ */
-+enum encoder_result dce110_stream_encoder_blank(
-+ struct stream_encoder *enc,
-+ enum signal_type signal)
-+{
-+ enum engine_id engine = enc->id;
-+ const uint32_t addr = mmDP_VID_STREAM_CNTL + fe_engine_offsets[engine];
-+ uint32_t value = dal_read_reg(enc->ctx, addr);
-+ uint32_t retries = 0;
-+ uint32_t max_retries = DP_BLANK_MAX_RETRY * 10;
-+
-+ if (!dc_is_dp_signal(signal))
-+ return ENCODER_RESULT_OK;
-+
-+ /* Note: For CZ, we are changing driver default to disable
-+ * stream deferred to next VBLANK. If results are positive, we
-+ * will make the same change to all DCE versions. There are a
-+ * handful of panels that cannot handle disable stream at
-+ * HBLANK and will result in a white line flash across the
-+ * screen on stream disable. */
-+
-+ /* Specify the video stream disable point
-+ * (2 = start of the next vertical blank) */
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ DP_VID_STREAM_CNTL,
-+ DP_VID_STREAM_DIS_DEFER);
-+ /* Larger delay to wait until VBLANK - use max retry of
-+ * 10us*3000=30ms. This covers 16.6ms of typical 60 Hz mode +
-+ * a little more because we may not trust delay accuracy. */
-+ max_retries = DP_BLANK_MAX_RETRY * 150;
-+
-+ /* disable DP stream */
-+ set_reg_field_value(value, 0, DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE);
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+ /* the encoder stops sending the video stream
-+ * at the start of the vertical blanking.
-+ * Poll for DP_VID_STREAM_STATUS == 0 */
-+
-+ do {
-+ value = dal_read_reg(enc->ctx, addr);
-+
-+ if (!get_reg_field_value(
-+ value,
-+ DP_VID_STREAM_CNTL,
-+ DP_VID_STREAM_STATUS))
-+ break;
-+
-+ dc_service_delay_in_microseconds(enc->ctx, 10);
-+
-+ ++retries;
-+ } while (retries < max_retries);
-+
-+ ASSERT(retries <= max_retries);
-+
-+ /* Tell the DP encoder to ignore timing from CRTC, must be done after
-+ * the polling. If we set DP_STEER_FIFO_RESET before DP stream blank is
-+ * complete, stream status will be stuck in video stream enabled state,
-+ * i.e. DP_VID_STREAM_STATUS stuck at 1. */
-+ dp_steer_fifo_reset(enc->ctx, engine, true);
-+
-+ return ENCODER_RESULT_OK;
-+}
-+
-+static void unblank_dp_output(
-+ struct stream_encoder *enc,
-+ enum engine_id engine)
-+{
-+ uint32_t addr;
-+ uint32_t value;
-+
-+ /* set DIG_START to 0x1 to resync FIFO */
-+ addr = mmDIG_FE_CNTL + fe_engine_offsets[engine];
-+ value = dal_read_reg(enc->ctx, addr);
-+ set_reg_field_value(value, 1, DIG_FE_CNTL, DIG_START);
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+ /* switch DP encoder to CRTC data */
-+ dp_steer_fifo_reset(enc->ctx, engine, false);
-+
-+ /* wait 100us for DIG/DP logic to prime
-+ * (i.e. a few video lines) */
-+ dc_service_delay_in_microseconds(enc->ctx, 100);
-+
-+ /* the hardware would start sending video at the start of the next DP
-+ * frame (i.e. rising edge of the vblank).
-+ * NOTE: We used to program DP_VID_STREAM_DIS_DEFER = 2 here, but this
-+ * register has no effect on enable transition! HW always guarantees
-+ * VID_STREAM enable at start of next frame, and this is not
-+ * programmable */
-+ addr = mmDP_VID_STREAM_CNTL + fe_engine_offsets[engine];
-+ value = dal_read_reg(enc->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ true,
-+ DP_VID_STREAM_CNTL,
-+ DP_VID_STREAM_ENABLE);
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+}
-+
-+static void setup_vid_stream(
-+ struct stream_encoder *enc,
-+ enum engine_id engine,
-+ uint32_t m_vid,
-+ uint32_t n_vid)
-+{
-+ uint32_t addr;
-+ uint32_t value;
-+
-+ /* enable auto measurement */
-+ addr = mmDP_VID_TIMING + fe_engine_offsets[engine];
-+ value = dal_read_reg(enc->ctx, addr);
-+ set_reg_field_value(value, 0, DP_VID_TIMING, DP_VID_M_N_GEN_EN);
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+ /* auto measurement need 1 full 0x8000 symbol cycle to kick in,
-+ * therefore program initial value for Mvid and Nvid */
-+ addr = mmDP_VID_N + fe_engine_offsets[engine];
-+ value = dal_read_reg(enc->ctx, addr);
-+ set_reg_field_value(value, n_vid, DP_VID_N, DP_VID_N);
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+ addr = mmDP_VID_M + fe_engine_offsets[engine];
-+ value = dal_read_reg(enc->ctx, addr);
-+ set_reg_field_value(value, m_vid, DP_VID_M, DP_VID_M);
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+ addr = mmDP_VID_TIMING + fe_engine_offsets[engine];
-+ value = dal_read_reg(enc->ctx, addr);
-+ set_reg_field_value(value, 1, DP_VID_TIMING, DP_VID_M_N_GEN_EN);
-+ dal_write_reg(enc->ctx, addr, value);
-+}
-+/*
-+ * @brief
-+ * Stop sending blank data,
-+ * output the actual surface data on active transmitter
-+ */
-+enum encoder_result dce110_stream_encoder_unblank(
-+ struct stream_encoder *enc,
-+ const struct encoder_unblank_param *param)
-+{
-+ bool is_dp_signal = param->signal == SIGNAL_TYPE_DISPLAY_PORT
-+ || param->signal == SIGNAL_TYPE_DISPLAY_PORT_MST
-+ || param->signal == SIGNAL_TYPE_EDP;
-+
-+ if (!is_dp_signal)
-+ return ENCODER_RESULT_OK;
-+
-+ if (param->link_settings.link_rate != LINK_RATE_UNKNOWN) {
-+ uint32_t n_vid = 0x8000;
-+ uint32_t m_vid;
-+
-+ /* M / N = Fstream / Flink
-+ * m_vid / n_vid = pixel rate / link rate */
-+
-+ uint64_t m_vid_l = n_vid;
-+
-+ m_vid_l *= param->crtc_timing.pixel_clock;
-+ m_vid_l = div_u64(m_vid_l,
-+ param->link_settings.link_rate
-+ * LINK_RATE_REF_FREQ_IN_KHZ);
-+
-+ m_vid = (uint32_t) m_vid_l;
-+
-+ setup_vid_stream(enc,
-+ enc->id, m_vid, n_vid);
-+ }
-+
-+ unblank_dp_output(enc, enc->id);
-+
-+ return ENCODER_RESULT_OK;
-+}
-+
-+static void set_dp_stream_attributes(
-+ struct stream_encoder *enc,
-+ enum engine_id engine,
-+ const struct dc_crtc_timing *timing)
-+{
-+ const uint32_t addr = mmDP_PIXEL_FORMAT + fe_engine_offsets[engine];
-+ uint32_t value = dal_read_reg(enc->ctx, addr);
-+
-+ /* set pixel encoding */
-+ switch (timing->pixel_encoding) {
-+ case PIXEL_ENCODING_YCBCR422:
-+ set_reg_field_value(
-+ value,
-+ DP_PIXEL_ENCODING_YCBCR422,
-+ DP_PIXEL_FORMAT,
-+ DP_PIXEL_ENCODING);
-+ break;
-+ case PIXEL_ENCODING_YCBCR444:
-+ set_reg_field_value(
-+ value,
-+ DP_PIXEL_ENCODING_YCBCR444,
-+ DP_PIXEL_FORMAT,
-+ DP_PIXEL_ENCODING);
-+
-+ if (timing->flags.Y_ONLY)
-+ if (timing->display_color_depth != COLOR_DEPTH_666)
-+ /* HW testing only, no use case yet.
-+ * Color depth of Y-only could be
-+ * 8, 10, 12, 16 bits */
-+ set_reg_field_value(
-+ value,
-+ DP_PIXEL_ENCODING_Y_ONLY,
-+ DP_PIXEL_FORMAT,
-+ DP_PIXEL_ENCODING);
-+ /* Note: DP_MSA_MISC1 bit 7 is the indicator
-+ * of Y-only mode.
-+ * This bit is set in HW if register
-+ * DP_PIXEL_ENCODING is programmed to 0x4 */
-+ break;
-+ default:
-+ set_reg_field_value(
-+ value,
-+ DP_PIXEL_ENCODING_RGB444,
-+ DP_PIXEL_FORMAT,
-+ DP_PIXEL_ENCODING);
-+ break;
-+ }
-+
-+ /* set color depth */
-+
-+ switch (timing->display_color_depth) {
-+ case COLOR_DEPTH_888:
-+ set_reg_field_value(
-+ value,
-+ DP_COMPONENT_DEPTH_8BPC,
-+ DP_PIXEL_FORMAT,
-+ DP_COMPONENT_DEPTH);
-+ break;
-+ case COLOR_DEPTH_101010:
-+ set_reg_field_value(
-+ value,
-+ DP_COMPONENT_DEPTH_10BPC,
-+ DP_PIXEL_FORMAT,
-+ DP_COMPONENT_DEPTH);
-+ break;
-+ case COLOR_DEPTH_121212:
-+ set_reg_field_value(
-+ value,
-+ DP_COMPONENT_DEPTH_12BPC,
-+ DP_PIXEL_FORMAT,
-+ DP_COMPONENT_DEPTH);
-+ break;
-+ default:
-+ set_reg_field_value(
-+ value,
-+ DP_COMPONENT_DEPTH_6BPC,
-+ DP_PIXEL_FORMAT,
-+ DP_COMPONENT_DEPTH);
-+ break;
-+ }
-+
-+ /* set dynamic range and YCbCr range */
-+ set_reg_field_value(value, 0, DP_PIXEL_FORMAT, DP_DYN_RANGE);
-+ set_reg_field_value(value, 0, DP_PIXEL_FORMAT, DP_YCBCR_RANGE);
-+
-+ dal_write_reg(enc->ctx, addr, value);
-+}
-+
-+static void setup_hdmi(
-+ struct stream_encoder *enc,
-+ enum engine_id engine,
-+ const struct dc_crtc_timing *timing)
-+{
-+ uint32_t output_pixel_clock = timing->pix_clk_khz;
-+ uint32_t value;
-+ uint32_t addr;
-+
-+ addr = mmHDMI_CONTROL + fe_engine_offsets[engine];
-+ value = dal_read_reg(enc->ctx, addr);
-+ set_reg_field_value(value, 1, HDMI_CONTROL, HDMI_PACKET_GEN_VERSION);
-+ set_reg_field_value(value, 1, HDMI_CONTROL, HDMI_KEEPOUT_MODE);
-+ set_reg_field_value(value, 0, HDMI_CONTROL, HDMI_DEEP_COLOR_ENABLE);
-+ set_reg_field_value(value, 0, HDMI_CONTROL, HDMI_DATA_SCRAMBLE_EN);
-+ set_reg_field_value(value, 0, HDMI_CONTROL, HDMI_CLOCK_CHANNEL_RATE);
-+
-+ switch (timing->display_color_depth) {
-+ case COLOR_DEPTH_888:
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_CONTROL,
-+ HDMI_DEEP_COLOR_DEPTH);
-+ break;
-+ case COLOR_DEPTH_101010:
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ HDMI_CONTROL,
-+ HDMI_DEEP_COLOR_DEPTH);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ HDMI_CONTROL,
-+ HDMI_DEEP_COLOR_ENABLE);
-+ output_pixel_clock = (timing->pix_clk_khz * 30) / 24;
-+ break;
-+ case COLOR_DEPTH_121212:
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ HDMI_CONTROL,
-+ HDMI_DEEP_COLOR_DEPTH);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ HDMI_CONTROL,
-+ HDMI_DEEP_COLOR_ENABLE);
-+ output_pixel_clock = (timing->pix_clk_khz * 36) / 24;
-+ break;
-+ case COLOR_DEPTH_161616:
-+ set_reg_field_value(
-+ value,
-+ 3,
-+ HDMI_CONTROL,
-+ HDMI_DEEP_COLOR_DEPTH);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ HDMI_CONTROL,
-+ HDMI_DEEP_COLOR_ENABLE);
-+ output_pixel_clock = (timing->pix_clk_khz * 48) / 24;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (output_pixel_clock >= HDMI_CLOCK_CHANNEL_RATE_MORE_340M) {
-+ /* enable HDMI data scrambler */
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ HDMI_CONTROL,
-+ HDMI_DATA_SCRAMBLE_EN);
-+
-+ /* HDMI_CLOCK_CHANNEL_RATE_MORE_340M
-+ * Clock channel frequency is 1/4 of character rate.*/
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ HDMI_CONTROL,
-+ HDMI_CLOCK_CHANNEL_RATE);
-+ } else if (timing->flags.LTE_340MCSC_SCRAMBLE) {
-+
-+ /* TODO: New feature for DCE11, still need to implement */
-+
-+ /* enable HDMI data scrambler */
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ HDMI_CONTROL,
-+ HDMI_DATA_SCRAMBLE_EN);
-+
-+ /* HDMI_CLOCK_CHANNEL_FREQ_EQUAL_TO_CHAR_RATE
-+ * Clock channel frequency is the same
-+ * as character rate */
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ HDMI_CONTROL,
-+ HDMI_CLOCK_CHANNEL_RATE);
-+ }
-+
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+ addr = mmHDMI_VBI_PACKET_CONTROL + fe_engine_offsets[engine];
-+ value = dal_read_reg(enc->ctx, addr);
-+ set_reg_field_value(value, 1, HDMI_VBI_PACKET_CONTROL, HDMI_GC_CONT);
-+ set_reg_field_value(value, 1, HDMI_VBI_PACKET_CONTROL, HDMI_GC_SEND);
-+ set_reg_field_value(value, 1, HDMI_VBI_PACKET_CONTROL, HDMI_NULL_SEND);
-+
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+ /* following belongs to audio */
-+ addr = mmHDMI_INFOFRAME_CONTROL0 + fe_engine_offsets[engine];
-+ value = dal_read_reg(enc->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ HDMI_INFOFRAME_CONTROL0,
-+ HDMI_AUDIO_INFO_SEND);
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+ addr = mmAFMT_INFOFRAME_CONTROL0 + fe_engine_offsets[engine];
-+ value = dal_read_reg(enc->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AFMT_INFOFRAME_CONTROL0,
-+ AFMT_AUDIO_INFO_UPDATE);
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+ addr = mmHDMI_INFOFRAME_CONTROL1 + fe_engine_offsets[engine];
-+ value = dal_read_reg(enc->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ VBI_LINE_0 + 2,
-+ HDMI_INFOFRAME_CONTROL1,
-+ HDMI_AUDIO_INFO_LINE);
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+ addr = mmHDMI_GC + fe_engine_offsets[engine];
-+ value = dal_read_reg(enc->ctx, addr);
-+ set_reg_field_value(value, 0, HDMI_GC, HDMI_GC_AVMUTE);
-+ dal_write_reg(enc->ctx, addr, value);
-+
-+}
-+
-+static void set_tmds_stream_attributes(
-+ struct stream_encoder *enc,
-+ enum engine_id engine,
-+ enum signal_type signal,
-+ const struct dc_crtc_timing *timing)
-+{
-+ uint32_t addr = mmDIG_FE_CNTL + fe_engine_offsets[engine];
-+ uint32_t value = dal_read_reg(enc->ctx, addr);
-+
-+ switch (timing->pixel_encoding) {
-+ case PIXEL_ENCODING_YCBCR422:
-+ set_reg_field_value(value, 1, DIG_FE_CNTL, TMDS_PIXEL_ENCODING);
-+ break;
-+ default:
-+ set_reg_field_value(value, 0, DIG_FE_CNTL, TMDS_PIXEL_ENCODING);
-+ break;
-+ }
-+
-+ switch (timing->pixel_encoding) {
-+ case COLOR_DEPTH_101010:
-+ if ((signal == SIGNAL_TYPE_DVI_SINGLE_LINK
-+ || signal == SIGNAL_TYPE_DVI_DUAL_LINK)
-+ && timing->pixel_encoding == PIXEL_ENCODING_RGB)
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ DIG_FE_CNTL,
-+ TMDS_COLOR_FORMAT);
-+ else
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DIG_FE_CNTL,
-+ TMDS_COLOR_FORMAT);
-+ break;
-+ default:
-+ set_reg_field_value(value, 0, DIG_FE_CNTL, TMDS_COLOR_FORMAT);
-+ break;
-+ }
-+ dal_write_reg(enc->ctx, addr, value);
-+}
-+
-+/*
-+ * @brief
-+ * Associate digital encoder with specified output transmitter
-+ * and configure to output signal.
-+ * Encoder will be activated later in enable_output()
-+ */
-+enum encoder_result dce110_stream_encoder_setup(
-+ struct stream_encoder *enc,
-+ struct dc_crtc_timing *crtc_timing,
-+ enum signal_type signal,
-+ bool enable_audio)
-+{
-+ if (!dc_is_dp_signal(signal)) {
-+ struct bp_encoder_control cntl;
-+
-+ cntl.action = ENCODER_CONTROL_SETUP;
-+ cntl.engine_id = enc->id;
-+ cntl.signal = signal;
-+ cntl.enable_dp_audio = enable_audio;
-+ cntl.pixel_clock = crtc_timing->pix_clk_khz;
-+ cntl.lanes_number = (signal == SIGNAL_TYPE_DVI_DUAL_LINK) ?
-+ LANE_COUNT_EIGHT : LANE_COUNT_FOUR;
-+ cntl.color_depth = crtc_timing->display_color_depth;
-+
-+ if (dal_bios_parser_encoder_control(
-+ dal_adapter_service_get_bios_parser(
-+ enc->adapter_service),
-+ &cntl) != BP_RESULT_OK)
-+ return ENCODER_RESULT_ERROR;
-+ }
-+
-+ switch (signal) {
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
-+ case SIGNAL_TYPE_DVI_DUAL_LINK:
-+ /* set signal format */
-+ set_tmds_stream_attributes(
-+ enc, enc->id, signal,
-+ crtc_timing);
-+ break;
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ /* set signal format */
-+ set_tmds_stream_attributes(
-+ enc, enc->id, signal,
-+ crtc_timing);
-+ /* setup HDMI engine */
-+ setup_hdmi(
-+ enc, enc->id, crtc_timing);
-+ break;
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP:
-+ /* set signal format */
-+ set_dp_stream_attributes(enc, enc->id, crtc_timing);
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return ENCODER_RESULT_OK;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.h
-new file mode 100644
-index 0000000..d2c7b90
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_stream_encoder.h
-@@ -0,0 +1,64 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_STREAM_ENCODER_DCE110_H__
-+#define __DC_STREAM_ENCODER_DCE110_H__
-+
-+struct stream_enc_init_data {
-+ enum engine_id stream_engine_id;
-+ struct adapter_service *adapter_service;
-+ struct dc_context *ctx;
-+};
-+
-+struct stream_encoder *dce110_stream_encoder_create(
-+ struct stream_enc_init_data *init);
-+
-+void dce110_stream_encoder_destroy(struct stream_encoder **enc);
-+
-+void dce110_stream_encoder_stop_info_packets(
-+ struct stream_encoder *enc,
-+ enum engine_id engine,
-+ enum signal_type signal);
-+
-+void dce110_stream_encoder_update_info_packets(
-+ struct stream_encoder *enc,
-+ enum signal_type signal,
-+ const struct encoder_info_frame *info_frame);
-+
-+enum encoder_result dce110_stream_encoder_blank(
-+ struct stream_encoder *enc,
-+ enum signal_type signal);
-+
-+enum encoder_result dce110_stream_encoder_unblank(
-+ struct stream_encoder *enc,
-+ const struct encoder_unblank_param *param);
-+
-+enum encoder_result dce110_stream_encoder_setup(
-+ struct stream_encoder *enc,
-+ struct dc_crtc_timing *crtc_timing,
-+ enum signal_type signal,
-+ bool enable_audio);
-+
-+#endif /* __DC_STREAM_ENCODER_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.c
-new file mode 100644
-index 0000000..198ff28
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.c
-@@ -0,0 +1,1878 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/* include DCE11 register header files */
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "dc_types.h"
-+
-+#include "include/grph_object_id.h"
-+#include "include/adapter_service_interface.h"
-+#include "include/logger_interface.h"
-+#include "include/timing_generator_types.h"
-+#include "dce110_timing_generator.h"
-+
-+
-+enum tg_regs_idx {
-+ IDX_CRTC_UPDATE_LOCK,
-+ IDX_CRTC_MASTER_UPDATE_LOCK,
-+ IDX_CRTC_MASTER_UPDATE_MODE,
-+ IDX_CRTC_H_TOTAL,
-+ IDX_CRTC_V_TOTAL,
-+ IDX_CRTC_H_BLANK_START_END,
-+ IDX_CRTC_V_BLANK_START_END,
-+ IDX_CRTC_H_SYNC_A,
-+ IDX_CRTC_V_SYNC_A,
-+ IDX_CRTC_H_SYNC_A_CNTL,
-+ IDX_CRTC_V_SYNC_A_CNTL,
-+ IDX_CRTC_INTERLACE_CONTROL,
-+ IDX_CRTC_BLANK_CONTROL,
-+ IDX_PIPE_PG_STATUS,
-+
-+ IDX_CRTC_TEST_PATTERN_COLOR,
-+ IDX_CRTC_TEST_PATTERN_CONTROL,
-+ IDX_CRTC_TEST_PATTERN_PARAMETERS,
-+ IDX_CRTC_FLOW_CONTROL,
-+ IDX_CRTC_STATUS,
-+ IDX_CRTC_STATUS_POSITION,
-+ IDX_CRTC_STATUS_FRAME_COUNT,
-+ IDX_CRTC_STEREO_CONTROL,
-+ IDX_CRTC_STEREO_STATUS,
-+ IDX_CRTC_STEREO_FORCE_NEXT_EYE,
-+ IDX_CRTC_3D_STRUCTURE_CONTROL,
-+ IDX_CRTC_DOUBLE_BUFFER_CONTROL,
-+ IDX_CRTC_V_TOTAL_MIN,
-+ IDX_CRTC_V_TOTAL_MAX,
-+ IDX_CRTC_V_TOTAL_CONTROL,
-+ IDX_CRTC_NOM_VERT_POSITION,
-+ IDX_CRTC_STATIC_SCREEN_CONTROL,
-+ IDX_CRTC_TRIGB_CNTL,
-+ IDX_CRTC_FORCE_COUNT_CNTL,
-+ IDX_CRTC_GSL_CONTROL,
-+ IDX_CRTC_GSL_WINDOW,
-+
-+ IDX_CRTC_CONTROL,
-+ IDX_CRTC_START_LINE_CONTROL,
-+ IDX_CRTC_COUNT_CONTROL,
-+
-+ IDX_MODE_EXT_OVERSCAN_LEFT_RIGHT,
-+ IDX_MODE_EXT_OVERSCAN_TOP_BOTTOM,
-+ IDX_DCP_GSL_CONTROL,
-+ IDX_GRPH_UPDATE,
-+
-+ IDX_CRTC_VBI_END,
-+
-+ IDX_BLND_UNDERFLOW_INTERRUPT,
-+ IDX_CRTC_BLACK_COLOR,
-+ IDX_CRTC_OVERSCAN_COLOR,
-+ IDX_CRTC_BLANK_DATA_COLOR,
-+
-+ TG_REGS_IDX_SIZE
-+};
-+
-+enum black_color_format {
-+ BLACK_COLOR_FORMAT_RGB_FULLRANGE = 0, /* used as index in array */
-+ BLACK_COLOR_FORMAT_RGB_LIMITED,
-+ BLACK_COLOR_FORMAT_YUV_TV,
-+ BLACK_COLOR_FORMAT_YUV_CV,
-+ BLACK_COLOR_FORMAT_YUV_SUPER_AA,
-+
-+ BLACK_COLOR_FORMAT_COUNT
-+};
-+
-+#define regs_for_controller(id)\
-+[CONTROLLER_ID_D ## id - 1] =\
-+{[IDX_CRTC_UPDATE_LOCK] = mmCRTC ## id ## _CRTC_UPDATE_LOCK,\
-+[IDX_CRTC_MASTER_UPDATE_LOCK] = mmCRTC ## id ## _CRTC_MASTER_UPDATE_LOCK,\
-+[IDX_CRTC_MASTER_UPDATE_MODE] = mmCRTC ## id ## _CRTC_MASTER_UPDATE_MODE,\
-+[IDX_CRTC_H_TOTAL] = mmCRTC ## id ## _CRTC_H_TOTAL,\
-+[IDX_CRTC_V_TOTAL] = mmCRTC ## id ## _CRTC_V_TOTAL,\
-+[IDX_CRTC_H_BLANK_START_END] = mmCRTC ## id ## _CRTC_H_BLANK_START_END,\
-+[IDX_CRTC_V_BLANK_START_END] = mmCRTC ## id ## _CRTC_V_BLANK_START_END,\
-+[IDX_CRTC_H_SYNC_A] = mmCRTC ## id ## _CRTC_H_SYNC_A,\
-+[IDX_CRTC_V_SYNC_A] = mmCRTC ## id ## _CRTC_V_SYNC_A,\
-+[IDX_CRTC_H_SYNC_A_CNTL] = mmCRTC ## id ## _CRTC_H_SYNC_A_CNTL,\
-+[IDX_CRTC_V_SYNC_A_CNTL] = mmCRTC ## id ## _CRTC_V_SYNC_A_CNTL,\
-+[IDX_CRTC_INTERLACE_CONTROL] = mmCRTC ## id ## _CRTC_INTERLACE_CONTROL,\
-+[IDX_CRTC_BLANK_CONTROL] = mmCRTC ## id ## _CRTC_BLANK_CONTROL,\
-+[IDX_PIPE_PG_STATUS] = mmPIPE ## id ## _PG_STATUS,\
-+[IDX_CRTC_TEST_PATTERN_COLOR] = mmCRTC ## id ## _CRTC_TEST_PATTERN_COLOR,\
-+[IDX_CRTC_TEST_PATTERN_CONTROL] = mmCRTC ## id ## _CRTC_TEST_PATTERN_CONTROL,\
-+[IDX_CRTC_TEST_PATTERN_PARAMETERS] =\
-+mmCRTC ## id ## _CRTC_TEST_PATTERN_PARAMETERS,\
-+[IDX_CRTC_FLOW_CONTROL] = mmCRTC ## id ## _CRTC_FLOW_CONTROL,\
-+[IDX_CRTC_STATUS] = mmCRTC ## id ## _CRTC_STATUS,\
-+[IDX_CRTC_STATUS_POSITION] = mmCRTC ## id ## _CRTC_STATUS_POSITION,\
-+[IDX_CRTC_STATUS_FRAME_COUNT] = mmCRTC ## id ## _CRTC_STATUS_FRAME_COUNT,\
-+[IDX_CRTC_STEREO_CONTROL] = mmCRTC ## id ## _CRTC_STEREO_CONTROL,\
-+[IDX_CRTC_STEREO_STATUS] = mmCRTC ## id ## _CRTC_STEREO_STATUS,\
-+[IDX_CRTC_STEREO_FORCE_NEXT_EYE] = \
-+mmCRTC ## id ## _CRTC_STEREO_FORCE_NEXT_EYE,\
-+[IDX_CRTC_3D_STRUCTURE_CONTROL] = mmCRTC ## id ## _CRTC_3D_STRUCTURE_CONTROL,\
-+[IDX_CRTC_DOUBLE_BUFFER_CONTROL] =\
-+mmCRTC ## id ## _CRTC_DOUBLE_BUFFER_CONTROL,\
-+[IDX_CRTC_V_TOTAL_MIN] = mmCRTC ## id ## _CRTC_V_TOTAL_MIN,\
-+[IDX_CRTC_V_TOTAL_MAX] = mmCRTC ## id ## _CRTC_V_TOTAL_MAX,\
-+[IDX_CRTC_V_TOTAL_CONTROL] = mmCRTC ## id ## _CRTC_V_TOTAL_CONTROL,\
-+[IDX_CRTC_NOM_VERT_POSITION] = mmCRTC ## id ## _CRTC_NOM_VERT_POSITION,\
-+[IDX_CRTC_STATIC_SCREEN_CONTROL] =\
-+mmCRTC ## id ## _CRTC_STATIC_SCREEN_CONTROL,\
-+[IDX_CRTC_TRIGB_CNTL] = mmCRTC ## id ## _CRTC_TRIGB_CNTL,\
-+[IDX_CRTC_FORCE_COUNT_CNTL] = mmCRTC ## id ## _CRTC_FORCE_COUNT_NOW_CNTL,\
-+[IDX_CRTC_GSL_CONTROL] = mmCRTC ## id ## _CRTC_GSL_CONTROL,\
-+[IDX_CRTC_GSL_WINDOW] = mmCRTC ## id ## _CRTC_GSL_WINDOW,\
-+[IDX_CRTC_CONTROL] = mmCRTC ## id ## _CRTC_CONTROL,\
-+[IDX_CRTC_START_LINE_CONTROL] = mmCRTC ## id ## _CRTC_START_LINE_CONTROL,\
-+[IDX_CRTC_COUNT_CONTROL] = mmCRTC ## id ## _CRTC_COUNT_CONTROL,\
-+[IDX_MODE_EXT_OVERSCAN_LEFT_RIGHT] = mmSCL ## id ## _EXT_OVERSCAN_LEFT_RIGHT,\
-+[IDX_MODE_EXT_OVERSCAN_TOP_BOTTOM] = mmSCL ## id ## _EXT_OVERSCAN_TOP_BOTTOM,\
-+[IDX_DCP_GSL_CONTROL] = mmDCP ## id ## _DCP_GSL_CONTROL,\
-+[IDX_GRPH_UPDATE] = mmDCP ## id ## _GRPH_UPDATE,\
-+[IDX_CRTC_VBI_END] = mmCRTC ## id ## _CRTC_VBI_END,\
-+[IDX_BLND_UNDERFLOW_INTERRUPT] = mmBLND ## id ## _BLND_UNDERFLOW_INTERRUPT,\
-+[IDX_CRTC_BLACK_COLOR] = mmCRTC ## id ## _CRTC_BLACK_COLOR,\
-+[IDX_CRTC_OVERSCAN_COLOR] = mmCRTC ## id ## _CRTC_OVERSCAN_COLOR,\
-+[IDX_CRTC_BLANK_DATA_COLOR] = mmCRTC ## id ## _CRTC_BLANK_DATA_COLOR,\
-+}
-+
-+#define NUMBER_OF_FRAME_TO_WAIT_ON_TRIGGERED_RESET 10
-+
-+#define MAX_H_TOTAL (CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1)
-+#define MAX_V_TOTAL (CRTC_V_TOTAL__CRTC_V_TOTAL_MASKhw + 1)
-+
-+
-+#define FROM_TIMING_GENERATOR(tg)\
-+ container_of(tg, struct dce110_timing_generator, base)
-+
-+static uint32_t tg_regs[][TG_REGS_IDX_SIZE] = {
-+ regs_for_controller(0),
-+ regs_for_controller(1),
-+ regs_for_controller(2),
-+};
-+
-+/*******************************************************************************
-+ * GSL Sync related values */
-+
-+/* In VSync mode, after 4 units of time, master pipe will generate
-+ * flip_ready signal */
-+#define VFLIP_READY_DELAY 4
-+/* In HSync mode, after 2 units of time, master pipe will generate
-+ * flip_ready signal */
-+#define HFLIP_READY_DELAY 2
-+/* 6 lines delay between forcing flip and checking all pipes ready */
-+#define HFLIP_CHECK_DELAY 6
-+/* 3 lines before end of frame */
-+#define FLIP_READY_BACK_LOOKUP 3
-+
-+/* Trigger Source Select - ASIC-dependant, actual values for the
-+ * register programming */
-+enum trigger_source_select {
-+ TRIGGER_SOURCE_SELECT_LOGIC_ZERO = 0,
-+ TRIGGER_SOURCE_SELECT_CRTC_VSYNCA = 1,
-+ TRIGGER_SOURCE_SELECT_CRTC_HSYNCA = 2,
-+ TRIGGER_SOURCE_SELECT_CRTC_VSYNCB = 3,
-+ TRIGGER_SOURCE_SELECT_CRTC_HSYNCB = 4,
-+ TRIGGER_SOURCE_SELECT_GENERICF = 5,
-+ TRIGGER_SOURCE_SELECT_GENERICE = 6,
-+ TRIGGER_SOURCE_SELECT_VSYNCA = 7,
-+ TRIGGER_SOURCE_SELECT_HSYNCA = 8,
-+ TRIGGER_SOURCE_SELECT_VSYNCB = 9,
-+ TRIGGER_SOURCE_SELECT_HSYNCB = 10,
-+ TRIGGER_SOURCE_SELECT_HPD1 = 11,
-+ TRIGGER_SOURCE_SELECT_HPD2 = 12,
-+ TRIGGER_SOURCE_SELECT_GENERICD = 13,
-+ TRIGGER_SOURCE_SELECT_GENERICC = 14,
-+ TRIGGER_SOURCE_SELECT_VIDEO_CAPTURE = 15,
-+ TRIGGER_SOURCE_SELECT_GSL_GROUP0 = 16,
-+ TRIGGER_SOURCE_SELECT_GSL_GROUP1 = 17,
-+ TRIGGER_SOURCE_SELECT_GSL_GROUP2 = 18,
-+ TRIGGER_SOURCE_SELECT_BLONY = 19,
-+ TRIGGER_SOURCE_SELECT_GENERICA = 20,
-+ TRIGGER_SOURCE_SELECT_GENERICB = 21,
-+ TRIGGER_SOURCE_SELECT_GSL_ALLOW_FLIP = 22,
-+ TRIGGER_SOURCE_SELECT_MANUAL_TRIGGER = 23
-+};
-+
-+/* Trigger Source Select - ASIC-dependant, actual values for the
-+ * register programming */
-+enum trigger_polarity_select {
-+ TRIGGER_POLARITY_SELECT_LOGIC_ZERO = 0,
-+ TRIGGER_POLARITY_SELECT_CRTC = 1,
-+ TRIGGER_POLARITY_SELECT_GENERICA = 2,
-+ TRIGGER_POLARITY_SELECT_GENERICB = 3,
-+ TRIGGER_POLARITY_SELECT_HSYNCA = 4,
-+ TRIGGER_POLARITY_SELECT_HSYNCB = 5,
-+ TRIGGER_POLARITY_SELECT_VIDEO_CAPTURE = 6,
-+ TRIGGER_POLARITY_SELECT_GENERICC = 7
-+};
-+
-+/******************************************************************************/
-+
-+bool dce110_timing_generator_construct(
-+ struct timing_generator *tg,
-+ enum controller_id id)
-+{
-+ tg->controller_id = id;
-+ return true;
-+}
-+
-+static const struct crtc_black_color black_color_format[] = {
-+ /* BlackColorFormat_RGB_FullRange */
-+ {0, 0, 0},
-+ /* BlackColorFormat_RGB_Limited */
-+ {CRTC_OVERSCAN_COLOR_BLACK_COLOR_B_RGB_LIMITED_RANGE,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_G_RGB_LIMITED_RANGE,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_R_RGB_LIMITED_RANGE},
-+ /* BlackColorFormat_YUV_TV */
-+ {CRTC_OVERSCAN_COLOR_BLACK_COLOR_B_CB_YUV_4TV,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_G_Y_YUV_4TV,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_R_CR_YUV_4TV},
-+ /* BlackColorFormat_YUV_CV */
-+ {CRTC_OVERSCAN_COLOR_BLACK_COLOR_B_CB_YUV_4CV,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_G_Y_YUV_4CV,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_R_CR_YUV_4CV},
-+ /* BlackColorFormat_YUV_SuperAA */
-+ {CRTC_OVERSCAN_COLOR_BLACK_COLOR_B_CB_YUV_4SUPERAA,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_G_Y_YUV_4SUPERAA,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_R_CR_YUV_4SUPERAA}
-+};
-+
-+void dce110_timing_generator_color_space_to_black_color(
-+ enum color_space colorspace,
-+ struct crtc_black_color *black_color)
-+{
-+ switch (colorspace) {
-+ case COLOR_SPACE_YPBPR601:
-+ *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_TV];
-+ break;
-+
-+ case COLOR_SPACE_YPBPR709:
-+ case COLOR_SPACE_YCBCR601:
-+ case COLOR_SPACE_YCBCR709:
-+ *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV];
-+ break;
-+
-+ case COLOR_SPACE_N_MVPU_SUPER_AA:
-+ /* In crossfire SuperAA mode, the slave overscan data is forced
-+ * to 0 in the pixel mixer on the master. As a result, we need
-+ * to adjust the blank color so that after blending the
-+ * master+slave, it will appear black
-+ */
-+ *black_color =
-+ black_color_format[BLACK_COLOR_FORMAT_YUV_SUPER_AA];
-+ break;
-+
-+ case COLOR_SPACE_SRGB_LIMITED_RANGE:
-+ *black_color =
-+ black_color_format[BLACK_COLOR_FORMAT_RGB_LIMITED];
-+ break;
-+
-+ default:
-+ /* fefault is sRGB black (full range). */
-+ *black_color =
-+ black_color_format[BLACK_COLOR_FORMAT_RGB_FULLRANGE];
-+ /* default is sRGB black 0. */
-+ break;
-+ }
-+}
-+
-+/**
-+* apply_front_porch_workaround
-+*
-+* This is a workaround for a bug that has existed since R5xx and has not been
-+* fixed keep Front porch at minimum 2 for Interlaced mode or 1 for progressive.
-+*/
-+void dce110_timing_generator_apply_front_porch_workaround(
-+ struct timing_generator *tg,
-+ struct dc_crtc_timing *timing)
-+{
-+ if (timing->flags.INTERLACE == 1) {
-+ if (timing->v_front_porch < 2)
-+ timing->v_front_porch = 2;
-+ } else {
-+ if (timing->v_front_porch < 1)
-+ timing->v_front_porch = 1;
-+ }
-+}
-+
-+int32_t dce110_timing_generator_get_vsynch_and_front_porch_size(
-+ const struct dc_crtc_timing *timing)
-+{
-+ return timing->v_sync_width + timing->v_front_porch;
-+}
-+
-+
-+void dce110_timing_generator_set_early_control(
-+ struct timing_generator *tg,
-+ uint32_t early_cntl)
-+{
-+ uint32_t regval;
-+ uint32_t address = tg->regs[IDX_CRTC_CONTROL];
-+
-+ regval = dal_read_reg(tg->ctx, address);
-+ set_reg_field_value(regval, early_cntl,
-+ CRTC_CONTROL, CRTC_HBLANK_EARLY_CONTROL);
-+ dal_write_reg(tg->ctx, address, regval);
-+}
-+
-+/**
-+ * Enable CRTC
-+ * Enable CRTC - call ASIC Control Object to enable Timing generator.
-+ */
-+bool dce110_timing_generator_enable_crtc(struct timing_generator *tg)
-+{
-+ enum bp_result result;
-+
-+ /* 0 value is needed by DRR and is also suggested default value for CZ
-+ */
-+ uint32_t value;
-+
-+ value = dal_read_reg(tg->ctx,
-+ tg->regs[IDX_CRTC_MASTER_UPDATE_MODE]);
-+ set_reg_field_value(value, 3,
-+ CRTC_MASTER_UPDATE_MODE, MASTER_UPDATE_MODE);
-+ dal_write_reg(tg->ctx,
-+ tg->regs[IDX_CRTC_MASTER_UPDATE_MODE], value);
-+
-+ result = dal_bios_parser_enable_crtc(tg->bp, tg->controller_id, true);
-+
-+ return result == BP_RESULT_OK;
-+}
-+
-+void dce110_timing_generator_program_blank_color(
-+ struct timing_generator *tg,
-+ enum color_space color_space)
-+{
-+ struct crtc_black_color black_color;
-+ uint32_t addr = tg->regs[IDX_CRTC_BLACK_COLOR];
-+ uint32_t value = dal_read_reg(tg->ctx, addr);
-+
-+ dce110_timing_generator_color_space_to_black_color(
-+ color_space,
-+ &black_color);
-+
-+ set_reg_field_value(
-+ value,
-+ black_color.black_color_b_cb,
-+ CRTC_BLACK_COLOR,
-+ CRTC_BLACK_COLOR_B_CB);
-+ set_reg_field_value(
-+ value,
-+ black_color.black_color_g_y,
-+ CRTC_BLACK_COLOR,
-+ CRTC_BLACK_COLOR_G_Y);
-+ set_reg_field_value(
-+ value,
-+ black_color.black_color_r_cr,
-+ CRTC_BLACK_COLOR,
-+ CRTC_BLACK_COLOR_R_CR);
-+
-+ dal_write_reg(tg->ctx, addr, value);
-+}
-+
-+/**
-+ * blank_crtc
-+ * Call ASIC Control Object to Blank CRTC.
-+ */
-+
-+bool dce110_timing_generator_blank_crtc(struct timing_generator *tg)
-+{
-+ uint32_t addr = tg->regs[IDX_CRTC_BLANK_CONTROL];
-+ uint32_t value = dal_read_reg(tg->ctx, addr);
-+ uint8_t counter = 100;
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ CRTC_BLANK_CONTROL,
-+ CRTC_BLANK_DATA_EN);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ CRTC_BLANK_CONTROL,
-+ CRTC_BLANK_DE_MODE);
-+
-+ dal_write_reg(tg->ctx, addr, value);
-+
-+ while (counter > 0) {
-+ value = dal_read_reg(tg->ctx, addr);
-+
-+ if (get_reg_field_value(
-+ value,
-+ CRTC_BLANK_CONTROL,
-+ CRTC_BLANK_DATA_EN) == 1 &&
-+ get_reg_field_value(
-+ value,
-+ CRTC_BLANK_CONTROL,
-+ CRTC_CURRENT_BLANK_STATE) == 1)
-+ break;
-+
-+ dc_service_sleep_in_milliseconds(tg->ctx, 1);
-+ counter--;
-+ }
-+
-+ if (!counter) {
-+ dal_logger_write(tg->ctx->logger, LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "timing generator %d blank timing out.\n",
-+ tg->controller_id);
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+/**
-+ * unblank_crtc
-+ * Call ASIC Control Object to UnBlank CRTC.
-+ */
-+bool dce110_timing_generator_unblank_crtc(struct timing_generator *tg)
-+{
-+ uint32_t addr = tg->regs[IDX_CRTC_BLANK_CONTROL];
-+ uint32_t value = dal_read_reg(tg->ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ CRTC_BLANK_CONTROL,
-+ CRTC_BLANK_DATA_EN);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ CRTC_BLANK_CONTROL,
-+ CRTC_BLANK_DE_MODE);
-+
-+ dal_write_reg(tg->ctx, addr, value);
-+
-+ return true;
-+}
-+
-+/**
-+ *****************************************************************************
-+ * Function: is_in_vertical_blank
-+ *
-+ * @brief
-+ * check the current status of CRTC to check if we are in Vertical Blank
-+ * regioneased" state
-+ *
-+ * @return
-+ * true if currently in blank region, false otherwise
-+ *
-+ *****************************************************************************
-+ */
-+bool dce110_timing_generator_is_in_vertical_blank(struct timing_generator *tg)
-+{
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+ uint32_t field = 0;
-+
-+ addr = tg->regs[IDX_CRTC_STATUS];
-+ value = dal_read_reg(tg->ctx, addr);
-+ field = get_reg_field_value(value, CRTC_STATUS, CRTC_V_BLANK);
-+ return field == 1;
-+}
-+
-+/**
-+ *****************************************************************************
-+ * Function: disable_stereo
-+ *
-+ * @brief
-+ * Disables active stereo on controller
-+ * Frame Packing need to be disabled in vBlank or when CRTC not running
-+ *****************************************************************************
-+ */
-+#if 0
-+@TODOSTEREO
-+static void disable_stereo(struct timing_generator *tg)
-+{
-+ uint32_t addr = tg->regs[IDX_CRTC_3D_STRUCTURE_CONTROL];
-+ uint32_t value = 0;
-+ uint32_t test = 0;
-+ uint32_t field = 0;
-+ uint32_t struc_en = 0;
-+ uint32_t struc_stereo_sel_ovr = 0;
-+
-+ value = dal_read_reg(tg->ctx, addr);
-+ struc_en = get_reg_field_value(
-+ value,
-+ CRTC_3D_STRUCTURE_CONTROL,
-+ CRTC_3D_STRUCTURE_EN);
-+
-+ struc_stereo_sel_ovr = get_reg_field_value(
-+ value,
-+ CRTC_3D_STRUCTURE_CONTROL,
-+ CRTC_3D_STRUCTURE_STEREO_SEL_OVR);
-+
-+ /*
-+ * When disabling Frame Packing in 2 step mode, we need to program both
-+ * registers at the same frame
-+ * Programming it in the beginning of VActive makes sure we are ok
-+ */
-+
-+ if (struc_en != 0 && struc_stereo_sel_ovr == 0) {
-+ tg->funcs->wait_for_vblank(tg);
-+ tg->funcs->wait_for_vactive(tg);
-+ }
-+
-+ value = 0;
-+ dal_write_reg(tg->ctx, addr, value);
-+
-+
-+ addr = tg->regs[IDX_CRTC_STEREO_CONTROL];
-+ dal_write_reg(tg->ctx, addr, value);
-+}
-+#endif
-+
-+/**
-+ * disable_crtc - call ASIC Control Object to disable Timing generator.
-+ */
-+bool dce110_timing_generator_disable_crtc(struct timing_generator *tg)
-+{
-+ enum bp_result result;
-+
-+ result = dal_bios_parser_enable_crtc(tg->bp, tg->controller_id, false);
-+
-+ /* Need to make sure stereo is disabled according to the DCE5.0 spec */
-+
-+ /*
-+ * @TODOSTEREO call this when adding stereo support
-+ * tg->funcs->disable_stereo(tg);
-+ */
-+
-+ return result == BP_RESULT_OK;
-+}
-+
-+/**
-+* program_horz_count_by_2
-+* Programs DxCRTC_HORZ_COUNT_BY2_EN - 1 for DVI 30bpp mode, 0 otherwise
-+*
-+*/
-+static void program_horz_count_by_2(
-+ struct timing_generator *tg,
-+ const struct dc_crtc_timing *timing)
-+{
-+ uint32_t regval;
-+
-+ regval = dal_read_reg(tg->ctx,
-+ tg->regs[IDX_CRTC_COUNT_CONTROL]);
-+
-+ set_reg_field_value(regval, 0, CRTC_COUNT_CONTROL,
-+ CRTC_HORZ_COUNT_BY2_EN);
-+
-+ if (timing->flags.HORZ_COUNT_BY_TWO)
-+ set_reg_field_value(regval, 1, CRTC_COUNT_CONTROL,
-+ CRTC_HORZ_COUNT_BY2_EN);
-+
-+ dal_write_reg(tg->ctx,
-+ tg->regs[IDX_CRTC_COUNT_CONTROL], regval);
-+}
-+
-+/**
-+ * program_timing_generator
-+ * Program CRTC Timing Registers - DxCRTC_H_*, DxCRTC_V_*, Pixel repetition.
-+ * Call ASIC Control Object to program Timings.
-+ */
-+bool dce110_timing_generator_program_timing_generator(
-+ struct timing_generator *tg,
-+ struct dc_crtc_timing *dc_crtc_timing)
-+{
-+ enum bp_result result;
-+ struct bp_hw_crtc_timing_parameters bp_params;
-+ uint32_t regval;
-+
-+ uint32_t vsync_offset = dc_crtc_timing->v_border_bottom +
-+ dc_crtc_timing->v_front_porch;
-+ uint32_t v_sync_start =dc_crtc_timing->v_addressable + vsync_offset;
-+
-+ uint32_t hsync_offset = dc_crtc_timing->h_border_right +
-+ dc_crtc_timing->h_front_porch;
-+ uint32_t h_sync_start = dc_crtc_timing->h_addressable + hsync_offset;
-+
-+ dc_service_memset(&bp_params, 0, sizeof(struct bp_hw_crtc_timing_parameters));
-+
-+ /* Due to an asic bug we need to apply the Front Porch workaround prior
-+ * to programming the timing.
-+ */
-+ dce110_timing_generator_apply_front_porch_workaround(tg, dc_crtc_timing);
-+
-+ bp_params.controller_id = tg->controller_id;
-+
-+ bp_params.h_total = dc_crtc_timing->h_total;
-+ bp_params.h_addressable =
-+ dc_crtc_timing->h_addressable;
-+ bp_params.v_total = dc_crtc_timing->v_total;
-+ bp_params.v_addressable = dc_crtc_timing->v_addressable;
-+
-+ bp_params.h_sync_start = h_sync_start;
-+ bp_params.h_sync_width = dc_crtc_timing->h_sync_width;
-+ bp_params.v_sync_start = v_sync_start;
-+ bp_params.v_sync_width = dc_crtc_timing->v_sync_width;
-+
-+ /* Set overscan */
-+ bp_params.h_overscan_left =
-+ dc_crtc_timing->h_border_left;
-+ bp_params.h_overscan_right =
-+ dc_crtc_timing->h_border_right;
-+ bp_params.v_overscan_top = dc_crtc_timing->v_border_top;
-+ bp_params.v_overscan_bottom =
-+ dc_crtc_timing->v_border_bottom;
-+
-+ /* Set flags */
-+ if (dc_crtc_timing->flags.HSYNC_POSITIVE_POLARITY == 1)
-+ bp_params.flags.HSYNC_POSITIVE_POLARITY = 1;
-+
-+ if (dc_crtc_timing->flags.VSYNC_POSITIVE_POLARITY == 1)
-+ bp_params.flags.VSYNC_POSITIVE_POLARITY = 1;
-+
-+ if (dc_crtc_timing->flags.INTERLACE == 1)
-+ bp_params.flags.INTERLACE = 1;
-+
-+ if (dc_crtc_timing->flags.HORZ_COUNT_BY_TWO == 1)
-+ bp_params.flags.HORZ_COUNT_BY_TWO = 1;
-+
-+ result = dal_bios_parser_program_crtc_timing(tg->bp, &bp_params);
-+
-+ program_horz_count_by_2(tg, dc_crtc_timing);
-+
-+
-+ regval = dal_read_reg(tg->ctx,
-+ tg->regs[IDX_CRTC_START_LINE_CONTROL]);
-+
-+ if (dce110_timing_generator_get_vsynch_and_front_porch_size(dc_crtc_timing) <= 3) {
-+ set_reg_field_value(regval, 3,
-+ CRTC_START_LINE_CONTROL,
-+ CRTC_ADVANCED_START_LINE_POSITION);
-+
-+ set_reg_field_value(regval, 0,
-+ CRTC_START_LINE_CONTROL,
-+ CRTC_PREFETCH_EN);
-+ } else {
-+ set_reg_field_value(regval, 4,
-+ CRTC_START_LINE_CONTROL,
-+ CRTC_ADVANCED_START_LINE_POSITION);
-+
-+ set_reg_field_value(regval, 1,
-+ CRTC_START_LINE_CONTROL,
-+ CRTC_PREFETCH_EN);
-+ }
-+ dal_write_reg(tg->ctx,
-+ tg->regs[IDX_CRTC_START_LINE_CONTROL], regval);
-+
-+ /* Enable stereo - only when we need to pack 3D frame. Other types
-+ * of stereo handled in explicit call */
-+
-+ /* TODOSTEREO
-+ if (hw_crtc_timing->flags.PACK_3D_FRAME) {
-+ struct crtc_stereo_parameters stereo_params = { false };
-+ stereo_params.PROGRAM_STEREO = true;
-+ stereo_params.PROGRAM_POLARITY = true;
-+ stereo_params.FRAME_PACKED = true;
-+ stereo_params.RIGHT_EYE_POLARITY =
-+ hw_crtc_timing->flags.RIGHT_EYE_3D_POLARITY;
-+ tg->funcs->enable_stereo(tg, &stereo_params);
-+ }*/
-+
-+ return result == BP_RESULT_OK;
-+}
-+
-+/**
-+ *****************************************************************************
-+ * Function: program_drr
-+ *
-+ * @brief
-+ * Program dynamic refresh rate registers m_DxCRTC_V_TOTAL_*.
-+ *
-+ * @param [in] pHwCrtcTiming: point to H
-+ * wCrtcTiming struct
-+ *****************************************************************************
-+ */
-+void dce110_timing_generator_program_drr(
-+ struct timing_generator *tg,
-+ const struct hw_ranged_timing *timing)
-+{
-+ /* register values */
-+ uint32_t v_total_min = 0;
-+ uint32_t v_total_max = 0;
-+ uint32_t v_total_cntl = 0;
-+ uint32_t static_screen_cntl = 0;
-+
-+ uint32_t addr = 0;
-+
-+ addr = tg->regs[IDX_CRTC_V_TOTAL_MIN];
-+ v_total_min = dal_read_reg(tg->ctx, addr);
-+
-+ addr = tg->regs[IDX_CRTC_V_TOTAL_MAX];
-+ v_total_max = dal_read_reg(tg->ctx, addr);
-+
-+ addr = tg->regs[IDX_CRTC_V_TOTAL_CONTROL];
-+ v_total_cntl = dal_read_reg(tg->ctx, addr);
-+
-+ addr = tg->regs[IDX_CRTC_STATIC_SCREEN_CONTROL];
-+ static_screen_cntl = dal_read_reg(tg->ctx, addr);
-+
-+ if (timing != NULL) {
-+ /* Set Static Screen trigger events
-+ * If CRTC_SET_V_TOTAL_MIN_MASK_EN is set, use legacy event mask
-+ * register
-+ */
-+ if (get_reg_field_value(
-+ v_total_cntl,
-+ CRTC_V_TOTAL_CONTROL,
-+ CRTC_SET_V_TOTAL_MIN_MASK_EN)) {
-+ set_reg_field_value(v_total_cntl,
-+ /* TODO: add implementation
-+ translate_to_dce_static_screen_events(
-+ timing->control.event_mask.u_all),
-+ */ 0,
-+ CRTC_V_TOTAL_CONTROL,
-+ CRTC_SET_V_TOTAL_MIN_MASK);
-+ } else {
-+ set_reg_field_value(static_screen_cntl,
-+ /* TODO: add implementation
-+ translate_to_dce_static_screen_events(
-+ timing->control.event_mask.u_all),
-+ */ 0,
-+ CRTC_STATIC_SCREEN_CONTROL,
-+ CRTC_STATIC_SCREEN_EVENT_MASK);
-+ }
-+
-+ /* Number of consecutive static screen frames before interrupt
-+ * is triggered. 0 is an invalid setting, which means we should
-+ * leaving HW setting unchanged. */
-+ if (timing->control.static_frame_count != 0) {
-+ set_reg_field_value(
-+ static_screen_cntl,
-+ timing->control.static_frame_count,
-+ CRTC_STATIC_SCREEN_CONTROL,
-+ CRTC_STATIC_SCREEN_FRAME_COUNT);
-+ }
-+
-+ /* This value is reduced by 1 based on the register definition
-+ * of the VTOTAL value:
-+ * CRTC_V_TOTAL should be set to Vertical total minus one. (E.g.
-+ * for 525 lines, set to 524 = 0x20C)
-+ */
-+ set_reg_field_value(v_total_min,
-+ timing->vertical_total_min,
-+ CRTC_V_TOTAL_MIN,
-+ CRTC_V_TOTAL_MIN);
-+ set_reg_field_value(v_total_max,
-+ timing->vertical_total_max,
-+ CRTC_V_TOTAL_MAX,
-+ CRTC_V_TOTAL_MAX);
-+
-+ /* set VTotalControl value according to ranged timing control.
-+ */
-+
-+ if (timing->vertical_total_min != 0) {
-+ set_reg_field_value(v_total_cntl,
-+ 1,
-+ CRTC_V_TOTAL_CONTROL,
-+ CRTC_V_TOTAL_MIN_SEL);
-+ } else {
-+ set_reg_field_value(v_total_cntl,
-+ 0,
-+ CRTC_V_TOTAL_CONTROL,
-+ CRTC_V_TOTAL_MIN_SEL);
-+ }
-+ if (timing->vertical_total_max != 0) {
-+ set_reg_field_value(v_total_cntl,
-+ 1,
-+ CRTC_V_TOTAL_CONTROL,
-+ CRTC_V_TOTAL_MAX_SEL);
-+ } else {
-+ set_reg_field_value(v_total_cntl,
-+ 0,
-+ CRTC_V_TOTAL_CONTROL,
-+ CRTC_V_TOTAL_MAX_SEL);
-+ }
-+ set_reg_field_value(v_total_cntl,
-+ timing->control.force_lock_on_event,
-+ CRTC_V_TOTAL_CONTROL,
-+ CRTC_FORCE_LOCK_ON_EVENT);
-+ set_reg_field_value(v_total_cntl,
-+ timing->control.lock_to_master_vsync,
-+ CRTC_V_TOTAL_CONTROL,
-+ CRTC_FORCE_LOCK_TO_MASTER_VSYNC);
-+ } else {
-+ set_reg_field_value(v_total_cntl,
-+ 0,
-+ CRTC_V_TOTAL_CONTROL,
-+ CRTC_SET_V_TOTAL_MIN_MASK);
-+ set_reg_field_value(static_screen_cntl,
-+ 0,
-+ CRTC_STATIC_SCREEN_CONTROL,
-+ CRTC_STATIC_SCREEN_EVENT_MASK);
-+ set_reg_field_value(v_total_min,
-+ 0,
-+ CRTC_V_TOTAL_MIN,
-+ CRTC_V_TOTAL_MIN);
-+ set_reg_field_value(v_total_max,
-+ 0,
-+ CRTC_V_TOTAL_MAX,
-+ CRTC_V_TOTAL_MAX);
-+ set_reg_field_value(v_total_cntl,
-+ 0,
-+ CRTC_V_TOTAL_CONTROL,
-+ CRTC_V_TOTAL_MIN_SEL);
-+ set_reg_field_value(v_total_cntl,
-+ 0,
-+ CRTC_V_TOTAL_CONTROL,
-+ CRTC_V_TOTAL_MAX_SEL);
-+ set_reg_field_value(v_total_cntl,
-+ 0,
-+ CRTC_V_TOTAL_CONTROL,
-+ CRTC_FORCE_LOCK_ON_EVENT);
-+ set_reg_field_value(v_total_cntl,
-+ 0,
-+ CRTC_V_TOTAL_CONTROL,
-+ CRTC_FORCE_LOCK_TO_MASTER_VSYNC);
-+ }
-+
-+ addr = tg->regs[IDX_CRTC_V_TOTAL_MIN];
-+ dal_write_reg(tg->ctx, addr, v_total_min);
-+
-+ addr = tg->regs[IDX_CRTC_V_TOTAL_MAX];
-+ dal_write_reg(tg->ctx, addr, v_total_max);
-+
-+ addr = tg->regs[IDX_CRTC_V_TOTAL_CONTROL];
-+ dal_write_reg(tg->ctx, addr, v_total_cntl);
-+
-+ addr = tg->regs[IDX_CRTC_STATIC_SCREEN_CONTROL];
-+ dal_write_reg(tg->ctx, addr, static_screen_cntl);
-+}
-+
-+/*
-+ * get_vblank_counter
-+ *
-+ * @brief
-+ * Get counter for vertical blanks. use register CRTC_STATUS_FRAME_COUNT which
-+ * holds the counter of frames.
-+ *
-+ * @param
-+ * struct timing_generator *tg - [in] timing generator which controls the
-+ * desired CRTC
-+ *
-+ * @return
-+ * Counter of frames, which should equal to number of vblanks.
-+ */
-+uint32_t dce110_timing_generator_get_vblank_counter(struct timing_generator *tg)
-+{
-+ uint32_t addr = tg->regs[IDX_CRTC_STATUS_FRAME_COUNT];
-+ uint32_t value = dal_read_reg(tg->ctx, addr);
-+ uint32_t field = get_reg_field_value(
-+ value, CRTC_STATUS_FRAME_COUNT, CRTC_FRAME_COUNT);
-+
-+ return field;
-+}
-+
-+/**
-+ *****************************************************************************
-+ * Function: dce110_get_crtc_positions
-+ *
-+ * @brief
-+ * Returns CRTC vertical/horizontal counters
-+ *
-+ * @param [out] v_position, h_position
-+ *****************************************************************************
-+ */
-+
-+void dce110_timing_generator_get_crtc_positions(
-+ struct timing_generator *tg,
-+ int32_t *h_position,
-+ int32_t *v_position)
-+{
-+ uint32_t value;
-+
-+ value = dal_read_reg(tg->ctx, tg->regs[IDX_CRTC_STATUS_POSITION]);
-+
-+ *h_position = get_reg_field_value(
-+ value,
-+ CRTC_STATUS_POSITION,
-+ CRTC_HORZ_COUNT);
-+
-+ *v_position = get_reg_field_value(
-+ value,
-+ CRTC_STATUS_POSITION,
-+ CRTC_VERT_COUNT);
-+}
-+
-+/**
-+ *****************************************************************************
-+ * Function: get_crtc_scanoutpos
-+ *
-+ * @brief
-+ * Returns CRTC vertical/horizontal counters
-+ *
-+ * @param [out] vpos, hpos
-+ *****************************************************************************
-+ */
-+uint32_t dce110_timing_generator_get_crtc_scanoutpos(
-+ struct timing_generator *tg,
-+ int32_t *vbl,
-+ int32_t *position)
-+{
-+ /* TODO 1: Update the implementation once caller is updated
-+ * WARNING!! This function is returning the whole register value
-+ * because the caller is expecting it instead of proper vertical and
-+ * horizontal position. This should be a temporary implementation
-+ * until the caller is updated. */
-+
-+ /* TODO 2: re-use dce110_timing_generator_get_crtc_positions() */
-+
-+ *vbl = dal_read_reg(tg->ctx,
-+ tg->regs[IDX_CRTC_V_BLANK_START_END]);
-+
-+ *position = dal_read_reg(tg->ctx,
-+ tg->regs[IDX_CRTC_STATUS_POSITION]);
-+
-+ /* @TODO: return value should indicate if current
-+ * crtc is inside vblank*/
-+ return 0;
-+}
-+
-+/* TODO: is it safe to assume that mask/shift of Primary and Underlay
-+ * are the same?
-+ * For example: today CRTC_H_TOTAL == CRTCV_H_TOTAL but is it always
-+ * guaranteed? */
-+void dce110_timing_generator_program_blanking(
-+ struct timing_generator *tg,
-+ const struct dc_crtc_timing *timing)
-+{
-+ uint32_t vsync_offset = timing->v_border_bottom +
-+ timing->v_front_porch;
-+ uint32_t v_sync_start =timing->v_addressable + vsync_offset;
-+
-+ uint32_t hsync_offset = timing->h_border_right +
-+ timing->h_front_porch;
-+ uint32_t h_sync_start = timing->h_addressable + hsync_offset;
-+
-+ struct dc_context *ctx = tg->ctx;
-+ uint32_t value = 0;
-+ uint32_t addr = 0;
-+ uint32_t tmp = 0;
-+
-+ addr = tg->regs[IDX_CRTC_H_TOTAL];
-+ value = dal_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ timing->h_total - 1,
-+ CRTC_H_TOTAL,
-+ CRTC_H_TOTAL);
-+ dal_write_reg(ctx, addr, value);
-+
-+ addr = tg->regs[IDX_CRTC_V_TOTAL];
-+ value = dal_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ timing->v_total - 1,
-+ CRTC_V_TOTAL,
-+ CRTC_V_TOTAL);
-+ dal_write_reg(ctx, addr, value);
-+
-+ addr = tg->regs[IDX_CRTC_H_BLANK_START_END];
-+ value = dal_read_reg(ctx, addr);
-+
-+ tmp = timing->h_total -
-+ (h_sync_start + timing->h_border_left);
-+
-+ set_reg_field_value(
-+ value,
-+ tmp,
-+ CRTC_H_BLANK_START_END,
-+ CRTC_H_BLANK_END);
-+
-+ tmp = tmp + timing->h_addressable +
-+ timing->h_border_left + timing->h_border_right;
-+
-+ set_reg_field_value(
-+ value,
-+ tmp,
-+ CRTC_H_BLANK_START_END,
-+ CRTC_H_BLANK_START);
-+
-+ dal_write_reg(ctx, addr, value);
-+
-+ addr = tg->regs[IDX_CRTC_V_BLANK_START_END];
-+ value = dal_read_reg(ctx, addr);
-+
-+ tmp = timing->v_total - (v_sync_start + timing->v_border_top);
-+
-+ set_reg_field_value(
-+ value,
-+ tmp,
-+ CRTC_V_BLANK_START_END,
-+ CRTC_V_BLANK_END);
-+
-+ tmp = tmp + timing->v_addressable + timing->v_border_top +
-+ timing->v_border_bottom;
-+
-+ set_reg_field_value(
-+ value,
-+ tmp,
-+ CRTC_V_BLANK_START_END,
-+ CRTC_V_BLANK_START);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+void dce110_timing_generator_set_test_pattern(
-+ struct timing_generator *tg,
-+ /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode'
-+ * because this is not DP-specific (which is probably somewhere in DP
-+ * encoder) */
-+ enum controller_dp_test_pattern test_pattern,
-+ enum dc_color_depth color_depth)
-+{
-+ struct dc_context *ctx = tg->ctx;
-+ uint32_t value;
-+ uint32_t addr;
-+
-+ /* TODO: add support for other test patterns */
-+ switch (test_pattern) {
-+ default:
-+ value = 0;
-+ addr = tg->regs[IDX_CRTC_TEST_PATTERN_PARAMETERS];
-+
-+ set_reg_field_value(
-+ value,
-+ 6,
-+ CRTC_TEST_PATTERN_PARAMETERS,
-+ CRTC_TEST_PATTERN_VRES);
-+ set_reg_field_value(
-+ value,
-+ 6,
-+ CRTC_TEST_PATTERN_PARAMETERS,
-+ CRTC_TEST_PATTERN_HRES);
-+
-+ dal_write_reg(ctx, addr, value);
-+
-+ addr = tg->regs[IDX_CRTC_TEST_PATTERN_CONTROL];
-+ value = 0;
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ CRTC_TEST_PATTERN_CONTROL,
-+ CRTC_TEST_PATTERN_EN);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ CRTC_TEST_PATTERN_CONTROL,
-+ CRTC_TEST_PATTERN_MODE);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ CRTC_TEST_PATTERN_CONTROL,
-+ CRTC_TEST_PATTERN_DYNAMIC_RANGE);
-+ /* add color depth translation here */
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ CRTC_TEST_PATTERN_CONTROL,
-+ CRTC_TEST_PATTERN_COLOR_FORMAT);
-+ dal_write_reg(ctx, addr, value);
-+ break;
-+ } /* switch() */
-+}
-+
-+/**
-+* dce110_timing_generator_validate_timing
-+* The timing generators support a maximum display size of is 8192 x 8192 pixels,
-+* including both active display and blanking periods. Check H Total and V Total.
-+*/
-+bool dce110_timing_generator_validate_timing(
-+ struct timing_generator *tg,
-+ const struct dc_crtc_timing *timing,
-+ enum signal_type signal)
-+{
-+ uint32_t h_blank;
-+ uint32_t h_back_porch;
-+ uint32_t hsync_offset = timing->h_border_right +
-+ timing->h_front_porch;
-+ uint32_t h_sync_start = timing->h_addressable + hsync_offset;
-+
-+ ASSERT(timing != NULL);
-+
-+ if (!timing)
-+ return false;
-+
-+ /* Check maximum number of pixels supported by Timing Generator
-+ * (Currently will never fail, in order to fail needs display which
-+ * needs more than 8192 horizontal and
-+ * more than 8192 vertical total pixels)
-+ */
-+ if (timing->h_total > tg->max_h_total ||
-+ timing->v_total > tg->max_v_total)
-+ return false;
-+
-+ h_blank = (timing->h_total - timing->h_addressable -
-+ timing->h_border_right -
-+ timing->h_border_left);
-+
-+ if (h_blank < tg->min_h_blank)
-+ return false;
-+
-+ if (timing->h_front_porch < tg->min_h_front_porch)
-+ return false;
-+
-+ h_back_porch = h_blank - (h_sync_start -
-+ timing->h_addressable -
-+ timing->h_border_right -
-+ timing->h_sync_width);
-+
-+ if (h_back_porch < tg->min_h_back_porch)
-+ return false;
-+
-+ return true;
-+}
-+
-+/**
-+* Wait till we are at the beginning of VBlank.
-+*/
-+void dce110_timing_generator_wait_for_vblank(struct timing_generator *tg)
-+{
-+ /* We want to catch beginning of VBlank here, so if the first try are
-+ * in VBlank, we might be very close to Active, in this case wait for
-+ * another frame
-+ */
-+ while (dce110_timing_generator_is_in_vertical_blank(tg)) {
-+ if (!dce110_timing_generator_is_counter_moving(tg)) {
-+ /* error - no point to wait if counter is not moving */
-+ break;
-+ }
-+ }
-+
-+ while (!dce110_timing_generator_is_in_vertical_blank(tg)) {
-+ if (!dce110_timing_generator_is_counter_moving(tg)) {
-+ /* error - no point to wait if counter is not moving */
-+ break;
-+ }
-+ }
-+}
-+
-+/**
-+* Wait till we are in VActive (anywhere in VActive)
-+*/
-+void dce110_timing_generator_wait_for_vactive(struct timing_generator *tg)
-+{
-+ while (dce110_timing_generator_is_in_vertical_blank(tg)) {
-+ if (!dce110_timing_generator_is_counter_moving(tg)) {
-+ /* error - no point to wait if counter is not moving */
-+ break;
-+ }
-+ }
-+}
-+
-+void dce110_timing_generator_destroy(struct timing_generator **tg)
-+{
-+ dc_service_free((*tg)->ctx, FROM_TIMING_GENERATOR(*tg));
-+ *tg = NULL;
-+}
-+
-+static bool timing_generator_dce110_construct(struct timing_generator *tg,
-+ struct dc_context *ctx,
-+ struct adapter_service *as,
-+ enum controller_id id)
-+{
-+ if (!as)
-+ return false;
-+
-+ switch (id) {
-+ case CONTROLLER_ID_D0:
-+ case CONTROLLER_ID_D1:
-+ case CONTROLLER_ID_D2:
-+ break;
-+ default:
-+ return false;
-+ }
-+
-+ if (!dce110_timing_generator_construct(tg, id))
-+ return false;
-+
-+ tg->ctx = ctx;
-+ tg->bp = dal_adapter_service_get_bios_parser(as);
-+ tg->regs = tg_regs[id-1];
-+
-+ tg->max_h_total = CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1;
-+ tg->max_v_total = CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1;
-+
-+ tg->min_h_blank = 56;
-+ tg->min_h_front_porch = 4;
-+ tg->min_h_back_porch = 4;
-+
-+ return true;
-+}
-+
-+struct timing_generator *dce110_timing_generator_create(
-+ struct adapter_service *as,
-+ struct dc_context *ctx,
-+ enum controller_id id)
-+{
-+ struct dce110_timing_generator *tg =
-+ dc_service_alloc(ctx, sizeof(struct dce110_timing_generator));
-+
-+ if (!tg)
-+ return NULL;
-+
-+ if (timing_generator_dce110_construct(&tg->base, ctx,
-+ as, id))
-+ return &tg->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dc_service_free(ctx, tg);
-+ return NULL;
-+}
-+
-+/**
-+ *****************************************************************************
-+ * Function: dce110_timing_generator_setup_global_swap_lock
-+ *
-+ * @brief
-+ * Setups Global Swap Lock group for current pipe
-+ * Pipe can join or leave GSL group, become a TimingServer or TimingClient
-+ *
-+ * @param [in] gsl_params: setup data
-+ *****************************************************************************
-+ */
-+
-+void dce110_timing_generator_setup_global_swap_lock(
-+ struct timing_generator *tg,
-+ const struct dcp_gsl_params *gsl_params)
-+{
-+ uint32_t value;
-+ uint32_t address = tg->regs[IDX_DCP_GSL_CONTROL];
-+ uint32_t check_point = FLIP_READY_BACK_LOOKUP;
-+
-+ value = dal_read_reg(tg->ctx, address);
-+
-+ /* This pipe will belong to GSL Group zero. */
-+ set_reg_field_value(value,
-+ 1,
-+ DCP_GSL_CONTROL,
-+ DCP_GSL0_EN);
-+
-+ set_reg_field_value(value,
-+ gsl_params->timing_server,
-+ DCP_GSL_CONTROL,
-+ DCP_GSL_MASTER_EN);
-+
-+ set_reg_field_value(value,
-+ HFLIP_READY_DELAY,
-+ DCP_GSL_CONTROL,
-+ DCP_GSL_HSYNC_FLIP_FORCE_DELAY);
-+
-+ /* Keep signal low (pending high) during 6 lines.
-+ * Also defines minimum interval before re-checking signal. */
-+ set_reg_field_value(value,
-+ HFLIP_CHECK_DELAY,
-+ DCP_GSL_CONTROL,
-+ DCP_GSL_HSYNC_FLIP_CHECK_DELAY);
-+
-+ /* DCP_GSL_PURPOSE_SURFACE_FLIP */
-+ {
-+ uint32_t value_crtc_vtotal;
-+
-+ value_crtc_vtotal = dal_read_reg(tg->ctx, tg->regs[IDX_CRTC_V_TOTAL]);
-+
-+ set_reg_field_value(value,
-+ gsl_params->gsl_purpose,
-+ DCP_GSL_CONTROL,
-+ DCP_GSL_SYNC_SOURCE);
-+
-+ /* Checkpoint relative to end of frame */
-+ check_point = get_reg_field_value(value_crtc_vtotal,
-+ CRTC_V_TOTAL,
-+ CRTC_V_TOTAL);
-+
-+ dal_write_reg(tg->ctx, tg->regs[IDX_CRTC_GSL_WINDOW], 0);
-+ }
-+
-+ set_reg_field_value(value,
-+ 1,
-+ DCP_GSL_CONTROL,
-+ DCP_GSL_DELAY_SURFACE_UPDATE_PENDING);
-+
-+ dal_write_reg(tg->ctx, address, value);
-+
-+ /********************************************************************/
-+ address = tg->regs[IDX_CRTC_GSL_CONTROL];
-+
-+ value = 0;
-+ set_reg_field_value(value,
-+ check_point - FLIP_READY_BACK_LOOKUP,
-+ CRTC_GSL_CONTROL,
-+ CRTC_GSL_CHECK_LINE_NUM);
-+
-+ set_reg_field_value(value,
-+ VFLIP_READY_DELAY,
-+ CRTC_GSL_CONTROL,
-+ CRTC_GSL_FORCE_DELAY);
-+
-+ dal_write_reg(tg->ctx, address, value);
-+}
-+
-+
-+void dce110_timing_generator_tear_down_global_swap_lock(
-+ struct timing_generator *tg)
-+{
-+ /* Clear all the register writes done by
-+ * dce110_timing_generator_setup_global_swap_lock
-+ */
-+
-+ uint32_t value;
-+ uint32_t address = tg->regs[IDX_DCP_GSL_CONTROL];
-+
-+ value = 0;
-+
-+ /* This pipe will belong to GSL Group zero. */
-+ /* Settig HW default values from reg specs */
-+ set_reg_field_value(value,
-+ 0,
-+ DCP_GSL_CONTROL,
-+ DCP_GSL0_EN);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ DCP_GSL_CONTROL,
-+ DCP_GSL_MASTER_EN);
-+
-+ set_reg_field_value(value,
-+ 0x2,
-+ DCP_GSL_CONTROL,
-+ DCP_GSL_HSYNC_FLIP_FORCE_DELAY);
-+
-+
-+ set_reg_field_value(value,
-+ 0x6,
-+ DCP_GSL_CONTROL,
-+ DCP_GSL_HSYNC_FLIP_CHECK_DELAY);
-+
-+ /* Restore DCP_GSL_PURPOSE_SURFACE_FLIP */
-+ {
-+ uint32_t value_crtc_vtotal;
-+
-+ value_crtc_vtotal = dal_read_reg(tg->ctx, tg->regs[IDX_CRTC_V_TOTAL]);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ DCP_GSL_CONTROL,
-+ DCP_GSL_SYNC_SOURCE);
-+ }
-+
-+ set_reg_field_value(value,
-+ 0,
-+ DCP_GSL_CONTROL,
-+ DCP_GSL_DELAY_SURFACE_UPDATE_PENDING);
-+
-+ dal_write_reg(tg->ctx, address, value);
-+
-+ /********************************************************************/
-+ address = tg->regs[IDX_CRTC_GSL_CONTROL];
-+
-+ value = 0;
-+ set_reg_field_value(value,
-+ 0,
-+ CRTC_GSL_CONTROL,
-+ CRTC_GSL_CHECK_LINE_NUM);
-+
-+ set_reg_field_value(value,
-+ 0x2,
-+ CRTC_GSL_CONTROL,
-+ CRTC_GSL_FORCE_DELAY);
-+
-+ dal_write_reg(tg->ctx, address, value);
-+}
-+/**
-+ *****************************************************************************
-+ * Function: is_counter_moving
-+ *
-+ * @brief
-+ * check if the timing generator is currently going
-+ *
-+ * @return
-+ * true if currently going, false if currently paused or stopped.
-+ *
-+ *****************************************************************************
-+ */
-+
-+bool dce110_timing_generator_is_counter_moving(struct timing_generator *tg)
-+{
-+ uint32_t addr = 0;
-+ uint32_t value_1 = 0;
-+ uint32_t field_1 = 0;
-+ uint32_t value_2 = 0;
-+ uint32_t field_2 = 0;
-+
-+ addr = tg->regs[IDX_CRTC_STATUS_POSITION];
-+ value_1 = dal_read_reg(tg->ctx, addr);
-+ value_2 = dal_read_reg(tg->ctx, addr);
-+
-+ field_1 = get_reg_field_value(
-+ value_1, CRTC_STATUS_POSITION, CRTC_HORZ_COUNT);
-+ field_2 = get_reg_field_value(
-+ value_2, CRTC_STATUS_POSITION, CRTC_HORZ_COUNT);
-+
-+ if (field_1 == field_2) {
-+ field_1 = get_reg_field_value(
-+ value_1, CRTC_STATUS_POSITION, CRTC_VERT_COUNT);
-+ field_2 = get_reg_field_value(
-+ value_2, CRTC_STATUS_POSITION, CRTC_VERT_COUNT);
-+ return field_1 != field_2;
-+ }
-+
-+ return true;
-+}
-+
-+/*TODO: Figure out if we need this function. */
-+void dce110_timing_generator_enable_advanced_request(
-+ struct timing_generator *tg,
-+ bool enable,
-+ const struct dc_crtc_timing *timing)
-+{
-+ uint32_t addr = tg->regs[IDX_CRTC_START_LINE_CONTROL];
-+ uint32_t value = dal_read_reg(tg->ctx, addr);
-+
-+ if (enable && FROM_TIMING_GENERATOR(tg)->advanced_request_enable) {
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ CRTC_START_LINE_CONTROL,
-+ CRTC_LEGACY_REQUESTOR_EN);
-+ } else {
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ CRTC_START_LINE_CONTROL,
-+ CRTC_LEGACY_REQUESTOR_EN);
-+ }
-+
-+ if (dce110_timing_generator_get_vsynch_and_front_porch_size(timing) <= 3) {
-+ set_reg_field_value(
-+ value,
-+ 3,
-+ CRTC_START_LINE_CONTROL,
-+ CRTC_ADVANCED_START_LINE_POSITION);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ CRTC_START_LINE_CONTROL,
-+ CRTC_PREFETCH_EN);
-+ } else {
-+ set_reg_field_value(
-+ value,
-+ 4,
-+ CRTC_START_LINE_CONTROL,
-+ CRTC_ADVANCED_START_LINE_POSITION);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ CRTC_START_LINE_CONTROL,
-+ CRTC_PREFETCH_EN);
-+ }
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ CRTC_START_LINE_CONTROL,
-+ CRTC_PROGRESSIVE_START_LINE_EARLY);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ CRTC_START_LINE_CONTROL,
-+ CRTC_INTERLACE_START_LINE_EARLY);
-+
-+ dal_write_reg(tg->ctx, addr, value);
-+}
-+
-+/*TODO: Figure out if we need this function. */
-+void dce110_timing_generator_set_lock_master(struct timing_generator *tg,
-+ bool lock)
-+{
-+ struct dc_context *ctx = tg->ctx;
-+ uint32_t addr = tg->regs[IDX_CRTC_MASTER_UPDATE_LOCK];
-+ uint32_t value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ lock ? 1 : 0,
-+ CRTC_MASTER_UPDATE_LOCK,
-+ MASTER_UPDATE_LOCK);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+void dce110_timing_generator_enable_reset_trigger(
-+ struct timing_generator *tg,
-+ const struct trigger_params *trigger_params)
-+{
-+ uint32_t value;
-+ struct dc_context *dc_ctx = tg->ctx;
-+ uint32_t rising_edge = 0;
-+ uint32_t falling_edge = 0;
-+ enum trigger_source_select trig_src_select = TRIGGER_SOURCE_SELECT_LOGIC_ZERO;
-+
-+ /* Setup trigger edge */
-+ switch (trigger_params->edge) {
-+ /* Default = based on current timing polarity */
-+ case TRIGGER_EDGE_DEFAULT:
-+ {
-+ uint32_t pol_value = dal_read_reg(tg->ctx,
-+ tg->regs[IDX_CRTC_V_SYNC_A_CNTL]);
-+
-+ /* Register spec has reversed definition:
-+ * 0 for positive, 1 for negative */
-+ if (get_reg_field_value(pol_value,
-+ CRTC_V_SYNC_A_CNTL,
-+ CRTC_V_SYNC_A_POL) == 0) {
-+ rising_edge = 1;
-+ } else {
-+ falling_edge = 1;
-+ }
-+ }
-+ break;
-+ case TRIGGER_EDGE_RISING:
-+ rising_edge = 1;
-+ break;
-+ case TRIGGER_EDGE_FALLING:
-+ falling_edge = 1;
-+ break;
-+ case TRIGGER_EDGE_BOTH:
-+ rising_edge = 1;
-+ falling_edge = 1;
-+ break;
-+ default:
-+ DC_ERROR("Invalid Trigger Edge!\n");
-+ return;
-+ }
-+
-+ value = dal_read_reg(tg->ctx, tg->regs[IDX_CRTC_TRIGB_CNTL]);
-+
-+ switch(trigger_params->source) {
-+ /* Currently supporting only a single group, the group zero. */
-+ case SYNC_SOURCE_GSL_GROUP0:
-+ trig_src_select = TRIGGER_SOURCE_SELECT_GSL_GROUP0;
-+ break;
-+ default:
-+ DC_ERROR("Unsupported GSL Group!\n");
-+ return;
-+ }
-+
-+ set_reg_field_value(value,
-+ trig_src_select,
-+ CRTC_TRIGB_CNTL,
-+ CRTC_TRIGB_SOURCE_SELECT);
-+
-+ set_reg_field_value(value,
-+ TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
-+ CRTC_TRIGB_CNTL,
-+ CRTC_TRIGB_POLARITY_SELECT);
-+
-+ set_reg_field_value(value,
-+ rising_edge,
-+ CRTC_TRIGB_CNTL,
-+ CRTC_TRIGB_RISING_EDGE_DETECT_CNTL);
-+
-+ set_reg_field_value(value,
-+ falling_edge,
-+ CRTC_TRIGB_CNTL,
-+ CRTC_TRIGB_FALLING_EDGE_DETECT_CNTL);
-+
-+ set_reg_field_value(value,
-+ 0, /* send every signal */
-+ CRTC_TRIGB_CNTL,
-+ CRTC_TRIGB_FREQUENCY_SELECT);
-+
-+ set_reg_field_value(value,
-+ 0, /* no delay */
-+ CRTC_TRIGB_CNTL,
-+ CRTC_TRIGB_DELAY);
-+
-+ set_reg_field_value(value,
-+ 1, /* clear trigger status */
-+ CRTC_TRIGB_CNTL,
-+ CRTC_TRIGB_CLEAR);
-+
-+ dal_write_reg(tg->ctx, tg->regs[IDX_CRTC_TRIGB_CNTL], value);
-+
-+ /**************************************************************/
-+
-+ value = dal_read_reg(tg->ctx, tg->regs[IDX_CRTC_FORCE_COUNT_CNTL]);
-+
-+ set_reg_field_value(value,
-+ 2, /* force H count to H_TOTAL and V count to V_TOTAL */
-+ CRTC_FORCE_COUNT_NOW_CNTL,
-+ CRTC_FORCE_COUNT_NOW_MODE);
-+
-+ set_reg_field_value(value,
-+ 1, /* TriggerB - we never use TriggerA */
-+ CRTC_FORCE_COUNT_NOW_CNTL,
-+ CRTC_FORCE_COUNT_NOW_TRIG_SEL);
-+
-+ set_reg_field_value(value,
-+ 1, /* clear trigger status */
-+ CRTC_FORCE_COUNT_NOW_CNTL,
-+ CRTC_FORCE_COUNT_NOW_CLEAR);
-+
-+ dal_write_reg(tg->ctx, tg->regs[IDX_CRTC_FORCE_COUNT_CNTL], value);
-+}
-+
-+void dce110_timing_generator_disable_reset_trigger(
-+ struct timing_generator *tg)
-+{
-+ uint32_t value;
-+
-+ value = dal_read_reg(tg->ctx, tg->regs[IDX_CRTC_FORCE_COUNT_CNTL]);
-+
-+ set_reg_field_value(value,
-+ 0, /* force counter now mode is disabled */
-+ CRTC_FORCE_COUNT_NOW_CNTL,
-+ CRTC_FORCE_COUNT_NOW_MODE);
-+
-+ set_reg_field_value(value,
-+ 1, /* clear trigger status */
-+ CRTC_FORCE_COUNT_NOW_CNTL,
-+ CRTC_FORCE_COUNT_NOW_CLEAR);
-+
-+ dal_write_reg(tg->ctx, tg->regs[IDX_CRTC_FORCE_COUNT_CNTL], value);
-+
-+ /********************************************************************/
-+ value = dal_read_reg(tg->ctx, tg->regs[IDX_CRTC_TRIGB_CNTL]);
-+
-+ set_reg_field_value(value,
-+ TRIGGER_SOURCE_SELECT_LOGIC_ZERO,
-+ CRTC_TRIGB_CNTL,
-+ CRTC_TRIGB_SOURCE_SELECT);
-+
-+ set_reg_field_value(value,
-+ TRIGGER_POLARITY_SELECT_LOGIC_ZERO,
-+ CRTC_TRIGB_CNTL,
-+ CRTC_TRIGB_POLARITY_SELECT);
-+
-+ set_reg_field_value(value,
-+ 1, /* clear trigger status */
-+ CRTC_TRIGB_CNTL,
-+ CRTC_TRIGB_CLEAR);
-+
-+ dal_write_reg(tg->ctx, tg->regs[IDX_CRTC_TRIGB_CNTL], value);
-+}
-+
-+/**
-+ *****************************************************************************
-+ * @brief
-+ * Checks whether CRTC triggered reset occurred
-+ *
-+ * @return
-+ * true if triggered reset occurred, false otherwise
-+ *****************************************************************************
-+ */
-+bool dce110_timing_generator_did_triggered_reset_occur(
-+ struct timing_generator *tg)
-+{
-+ uint32_t value = dal_read_reg(tg->ctx, tg->regs[IDX_CRTC_FORCE_COUNT_CNTL]);
-+
-+ return get_reg_field_value(value,
-+ CRTC_FORCE_COUNT_NOW_CNTL,
-+ CRTC_FORCE_COUNT_NOW_OCCURRED) != 0;
-+}
-+
-+/**
-+ * dce110_timing_generator_disable_vga
-+ * Turn OFF VGA Mode and Timing - DxVGA_CONTROL
-+ * VGA Mode and VGA Timing is used by VBIOS on CRT Monitors;
-+ */
-+void dce110_timing_generator_disable_vga(
-+ struct timing_generator *tg)
-+{
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+
-+ switch (tg->controller_id) {
-+ case CONTROLLER_ID_D0:
-+ addr = mmD1VGA_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D1:
-+ addr = mmD2VGA_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D2:
-+ addr = mmD3VGA_CONTROL;
-+ break;
-+ default:
-+ break;
-+ }
-+ value = dal_read_reg(tg->ctx, addr);
-+
-+ set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_MODE_ENABLE);
-+ set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_TIMING_SELECT);
-+ set_reg_field_value(
-+ value, 0, D1VGA_CONTROL, D1VGA_SYNC_POLARITY_SELECT);
-+ set_reg_field_value(value, 0, D1VGA_CONTROL, D1VGA_OVERSCAN_COLOR_EN);
-+
-+ dal_write_reg(tg->ctx, addr, value);
-+}
-+
-+
-+/**
-+* set_overscan_color_black
-+*
-+* @param :black_color is one of the color space
-+* :this routine will set overscan black color according to the color space.
-+* @return none
-+*/
-+
-+void dce110_timing_generator_set_overscan_color_black(
-+ struct timing_generator *tg,
-+ enum color_space black_color)
-+{
-+ struct dc_context *ctx = tg->ctx;
-+ uint32_t value = 0;
-+ uint32_t addr;
-+
-+ /* Overscan Color for YUV display modes:
-+ * to achieve a black color for both the explicit and implicit overscan,
-+ * the overscan color registers should be programmed to: */
-+
-+ switch (black_color) {
-+ case COLOR_SPACE_YPBPR601:
-+ set_reg_field_value(
-+ value,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_B_CB_YUV_4TV,
-+ CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_BLUE);
-+
-+ set_reg_field_value(
-+ value,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_G_Y_YUV_4TV,
-+ CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_GREEN);
-+
-+ set_reg_field_value(
-+ value,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_R_CR_YUV_4TV,
-+ CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_RED);
-+ break;
-+
-+ case COLOR_SPACE_YPBPR709:
-+ case COLOR_SPACE_YCBCR601:
-+ case COLOR_SPACE_YCBCR709:
-+ case COLOR_SPACE_YCBCR601_YONLY:
-+ case COLOR_SPACE_YCBCR709_YONLY:
-+ set_reg_field_value(
-+ value,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_B_CB_YUV_4CV,
-+ CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_BLUE);
-+
-+ set_reg_field_value(
-+ value,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_G_Y_YUV_4TV,
-+ CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_GREEN);
-+
-+ set_reg_field_value(
-+ value,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_R_CR_YUV_4CV,
-+ CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_RED);
-+ break;
-+
-+ case COLOR_SPACE_N_MVPU_SUPER_AA:
-+ /* In crossfire SuperAA mode, the slave overscan data is forced
-+ * to 0 in the pixel mixer on the master. As a result, we need
-+ * to adjust the blank color so that after blending the
-+ * master+slave, it will appear black */
-+ set_reg_field_value(
-+ value,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_B_CB_YUV_4SUPERAA,
-+ CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_BLUE);
-+
-+ set_reg_field_value(
-+ value,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_G_Y_YUV_4SUPERAA,
-+ CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_GREEN);
-+
-+ set_reg_field_value(
-+ value,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_R_CR_YUV_4SUPERAA,
-+ CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_RED);
-+ break;
-+
-+ case COLOR_SPACE_SRGB_LIMITED_RANGE:
-+ set_reg_field_value(
-+ value,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_B_RGB_LIMITED_RANGE,
-+ CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_BLUE);
-+
-+ set_reg_field_value(
-+ value,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_G_RGB_LIMITED_RANGE,
-+ CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_GREEN);
-+
-+ set_reg_field_value(
-+ value,
-+ CRTC_OVERSCAN_COLOR_BLACK_COLOR_R_RGB_LIMITED_RANGE,
-+ CRTC_OVERSCAN_COLOR,
-+ CRTC_OVERSCAN_COLOR_RED);
-+ break;
-+
-+ default:
-+ /* default is sRGB black 0. */
-+ break;
-+ }
-+ addr = tg->regs[IDX_CRTC_OVERSCAN_COLOR];
-+ dal_write_reg(ctx, addr, value);
-+ addr = tg->regs[IDX_CRTC_BLACK_COLOR];
-+ dal_write_reg(ctx, addr, value);
-+ /* This is desirable to have a constant DAC output voltage during the
-+ * blank time that is higher than the 0 volt reference level that the
-+ * DAC outputs when the NBLANK signal
-+ * is asserted low, such as for output to an analog TV. */
-+ addr = tg->regs[IDX_CRTC_BLANK_DATA_COLOR];
-+ dal_write_reg(ctx, addr, value);
-+
-+ /* TO DO we have to program EXT registers and we need to know LB DATA
-+ * format because it is used when more 10 , i.e. 12 bits per color
-+ *
-+ * m_mmDxCRTC_OVERSCAN_COLOR_EXT
-+ * m_mmDxCRTC_BLACK_COLOR_EXT
-+ * m_mmDxCRTC_BLANK_DATA_COLOR_EXT
-+ */
-+
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.h
-new file mode 100644
-index 0000000..d95a2a0
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.h
-@@ -0,0 +1,178 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_TIMING_GENERATOR_DCE110_H__
-+#define __DC_TIMING_GENERATOR_DCE110_H__
-+
-+
-+#include "../include/timing_generator_types.h"
-+#include "../include/grph_object_id.h"
-+
-+/* overscan in blank for YUV color space. For RGB, it is zero for black. */
-+#define CRTC_OVERSCAN_COLOR_BLACK_COLOR_B_CB_YUV_4CV 0x1f4
-+#define CRTC_OVERSCAN_COLOR_BLACK_COLOR_G_Y_YUV_4CV 0x40
-+#define CRTC_OVERSCAN_COLOR_BLACK_COLOR_R_CR_YUV_4CV 0x1f4
-+
-+#define CRTC_OVERSCAN_COLOR_BLACK_COLOR_B_CB_YUV_4TV 0x200
-+#define CRTC_OVERSCAN_COLOR_BLACK_COLOR_G_Y_YUV_4TV 0x40
-+#define CRTC_OVERSCAN_COLOR_BLACK_COLOR_R_CR_YUV_4TV 0x200
-+
-+/* overscan in blank for YUV color space when in SuperAA crossfire mode */
-+#define CRTC_OVERSCAN_COLOR_BLACK_COLOR_B_CB_YUV_4SUPERAA 0x1a2
-+#define CRTC_OVERSCAN_COLOR_BLACK_COLOR_G_Y_YUV_4SUPERAA 0x20
-+#define CRTC_OVERSCAN_COLOR_BLACK_COLOR_R_CR_YUV_4SUPERAA 0x1a2
-+
-+/* OVERSCAN COLOR FOR RGB LIMITED RANGE
-+ * (16~253) 16*4 (Multiple over 256 code leve) =64 (0x40) */
-+#define CRTC_OVERSCAN_COLOR_BLACK_COLOR_B_RGB_LIMITED_RANGE 0x40
-+#define CRTC_OVERSCAN_COLOR_BLACK_COLOR_G_RGB_LIMITED_RANGE 0x40
-+#define CRTC_OVERSCAN_COLOR_BLACK_COLOR_R_RGB_LIMITED_RANGE 0X40
-+
-+struct dce110_timing_generator {
-+ struct timing_generator base;
-+ enum sync_source cached_gsl_group;
-+ bool advanced_request_enable;
-+};
-+
-+struct timing_generator *dce110_timing_generator_create(
-+ struct adapter_service *as,
-+ struct dc_context *ctx,
-+ enum controller_id id);
-+
-+void dce110_timing_generator_destroy(struct timing_generator **tg);
-+
-+bool dce110_timing_generator_construct(
-+ struct timing_generator *tg,
-+ enum controller_id id);
-+
-+void dce110_timing_generator_program_blank_color(
-+ struct timing_generator *tg,
-+ enum color_space color_space);
-+
-+bool dce110_timing_generator_blank_crtc(struct timing_generator *tg);
-+
-+bool dce110_timing_generator_enable_crtc(struct timing_generator *tg);
-+
-+bool dce110_timing_generator_disable_crtc(struct timing_generator *tg);
-+
-+bool dce110_timing_generator_is_in_vertical_blank(struct timing_generator *tg);
-+
-+void dce110_timing_generator_program_blanking(
-+ struct timing_generator *tg,
-+ const struct dc_crtc_timing *timing);
-+
-+bool dce110_timing_generator_program_timing_generator(
-+ struct timing_generator *tg,
-+ struct dc_crtc_timing *dc_crtc_timing);
-+
-+void dce110_timing_generator_set_early_control(
-+ struct timing_generator *tg,
-+ uint32_t early_cntl);
-+
-+bool dce110_timing_generator_unblank_crtc(struct timing_generator *tg);
-+
-+bool dce110_timing_generator_validate_timing(
-+ struct timing_generator *tg,
-+ const struct dc_crtc_timing *timing,
-+ enum signal_type signal);
-+
-+void dce110_timing_generator_wait_for_vblank(struct timing_generator *tg);
-+
-+void dce110_timing_generator_wait_for_vactive(struct timing_generator *tg);
-+
-+void dce110_timing_generator_set_test_pattern(
-+ struct timing_generator *tg,
-+ /* TODO: replace 'controller_dp_test_pattern' by 'test_pattern_mode'
-+ * because this is not DP-specific (which is probably somewhere in DP
-+ * encoder) */
-+ enum controller_dp_test_pattern test_pattern,
-+ enum dc_color_depth color_depth);
-+
-+void dce110_timing_generator_program_drr(
-+ struct timing_generator *tg,
-+ const struct hw_ranged_timing *timing);
-+
-+uint32_t dce110_timing_generator_get_crtc_scanoutpos(
-+ struct timing_generator *tg,
-+ int32_t *vbl,
-+ int32_t *position);
-+
-+uint32_t dce110_timing_generator_get_vblank_counter(struct timing_generator *tg);
-+
-+void dce110_timing_generator_color_space_to_black_color(
-+ enum color_space colorspace,
-+ struct crtc_black_color *black_color);
-+void dce110_timing_generator_apply_front_porch_workaround(
-+ struct timing_generator *tg,
-+ struct dc_crtc_timing *timing);
-+int32_t dce110_timing_generator_get_vsynch_and_front_porch_size(
-+ const struct dc_crtc_timing *timing);
-+
-+void dce110_timing_generator_get_crtc_positions(
-+ struct timing_generator *tg,
-+ int32_t *h_position,
-+ int32_t *v_position);
-+
-+
-+/* TODO: Figure out if we need these functions*/
-+bool dce110_timing_generator_is_counter_moving(struct timing_generator *tg);
-+
-+void dce110_timing_generator_enable_advanced_request(
-+ struct timing_generator *tg,
-+ bool enable,
-+ const struct dc_crtc_timing *timing);
-+
-+void dce110_timing_generator_set_lock_master(struct timing_generator *tg,
-+ bool lock);
-+
-+void dce110_timing_generator_set_overscan_color_black(
-+ struct timing_generator *tg,
-+ enum color_space black_color);
-+
-+
-+/**** Sync-related interfaces ****/
-+void dce110_timing_generator_setup_global_swap_lock(
-+ struct timing_generator *tg,
-+ const struct dcp_gsl_params *gsl_params);
-+void dce110_timing_generator_tear_down_global_swap_lock(
-+ struct timing_generator *tg);
-+
-+
-+void dce110_timing_generator_enable_reset_trigger(
-+ struct timing_generator *tg,
-+ const struct trigger_params *trigger_params);
-+
-+void dce110_timing_generator_disable_reset_trigger(
-+ struct timing_generator *tg);
-+
-+bool dce110_timing_generator_did_triggered_reset_occur(
-+ struct timing_generator *tg);
-+
-+void dce110_timing_generator_disable_vga(
-+ struct timing_generator *tg);
-+
-+/**** End-of-Sync-related interfaces ****/
-+
-+#endif /* __DC_TIMING_GENERATOR_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform.c
-new file mode 100644
-index 0000000..f3b3630
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform.c
-@@ -0,0 +1,116 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/* include DCE11 register header files */
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "dc_types.h"
-+#include "core_types.h"
-+
-+#include "include/grph_object_id.h"
-+#include "include/fixed31_32.h"
-+#include "include/logger_interface.h"
-+
-+#include "dce110_transform.h"
-+#include "dce110_transform_bit_depth.h"
-+
-+static const struct dce110_transform_reg_offsets reg_offsets[] = {
-+{
-+ .scl_offset = (mmSCL0_SCL_CONTROL - mmSCL0_SCL_CONTROL),
-+ .dcfe_offset = (mmDCFE0_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .lb_offset = (mmLB0_LB_DATA_FORMAT - mmLB0_LB_DATA_FORMAT),
-+},
-+{ .scl_offset = (mmSCL1_SCL_CONTROL - mmSCL0_SCL_CONTROL),
-+ .dcfe_offset = (mmDCFE1_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .lb_offset = (mmLB1_LB_DATA_FORMAT - mmLB0_LB_DATA_FORMAT),
-+},
-+{ .scl_offset = (mmSCL2_SCL_CONTROL - mmSCL0_SCL_CONTROL),
-+ .dcfe_offset = (mmDCFE2_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .lb_offset = (mmLB2_LB_DATA_FORMAT - mmLB0_LB_DATA_FORMAT),
-+}
-+};
-+
-+/*****************************************/
-+/* Constructor, Destructor */
-+/*****************************************/
-+
-+bool dce110_transform_construct(
-+ struct dce110_transform *xfm110,
-+ struct dc_context *ctx,
-+ uint32_t inst)
-+{
-+ if ((inst < 1) || (inst > ARRAY_SIZE(reg_offsets)))
-+ return false;
-+
-+ xfm110->base.ctx = ctx;
-+
-+ xfm110->base.inst = inst;
-+
-+ xfm110->offsets = reg_offsets[inst - 1];
-+
-+ xfm110->lb_pixel_depth_supported =
-+ LB_PIXEL_DEPTH_18BPP |
-+ LB_PIXEL_DEPTH_24BPP |
-+ LB_PIXEL_DEPTH_30BPP;
-+
-+ return true;
-+}
-+
-+void dce110_transform_destroy(struct transform **xfm)
-+{
-+ dc_service_free((*xfm)->ctx, TO_DCE110_TRANSFORM(*xfm));
-+ *xfm = NULL;
-+}
-+
-+struct transform *dce110_transform_create(
-+ struct dc_context *ctx,
-+ uint32_t inst)
-+{
-+ struct dce110_transform *transform =
-+ dc_service_alloc(ctx, sizeof(struct dce110_transform));
-+
-+ if (!transform)
-+ return NULL;
-+
-+ if (dce110_transform_construct(transform,
-+ ctx, inst))
-+ return &transform->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dc_service_free(ctx, transform);
-+ return NULL;
-+}
-+
-+bool dce110_transform_power_up(struct transform *xfm)
-+{
-+ return dce110_transform_power_up_line_buffer(xfm);
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform.h
-new file mode 100644
-index 0000000..edf016c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform.h
-@@ -0,0 +1,91 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_TRANSFORM_DCE110_H__
-+#define __DAL_TRANSFORM_DCE110_H__
-+
-+#include "inc/transform.h"
-+#include "include/grph_csc_types.h"
-+
-+#define TO_DCE110_TRANSFORM(transform)\
-+ container_of(transform, struct dce110_transform, base)
-+
-+struct dce110_transform_reg_offsets {
-+ uint32_t scl_offset;
-+ uint32_t dcfe_offset;
-+ uint32_t dcp_offset;
-+ uint32_t lb_offset;
-+};
-+
-+struct dce110_transform {
-+ struct transform base;
-+ struct dce110_transform_reg_offsets offsets;
-+
-+ uint32_t lb_pixel_depth_supported;
-+};
-+
-+bool dce110_transform_construct(struct dce110_transform *xfm110,
-+ struct dc_context *ctx,
-+ uint32_t inst);
-+
-+void dce110_transform_destroy(struct transform **xfm);
-+
-+struct transform *dce110_transform_create(
-+ struct dc_context *ctx,
-+ uint32_t inst);
-+
-+bool dce110_transform_power_up(struct transform *xfm);
-+
-+/* SCALER RELATED */
-+bool dce110_transform_set_scaler(
-+ struct transform *xfm,
-+ const struct scaler_data *data);
-+
-+void dce110_transform_set_scaler_bypass(struct transform *xfm);
-+
-+bool dce110_transform_update_viewport(
-+ struct transform *xfm,
-+ const struct rect *view_port,
-+ bool is_fbc_attached);
-+
-+void dce110_transform_set_scaler_filter(
-+ struct transform *xfm,
-+ struct scaler_filter *filter);
-+
-+/* GAMUT RELATED */
-+void dce110_transform_set_gamut_remap(
-+ struct transform *xfm,
-+ const struct grph_csc_adjustment *adjust);
-+
-+/* BIT DEPTH RELATED */
-+bool dce110_transform_set_pixel_storage_depth(
-+ struct transform *xfm,
-+ enum lb_pixel_depth depth);
-+
-+bool dce110_transform_get_current_pixel_storage_depth(
-+ struct transform *xfm,
-+ enum lb_pixel_depth *depth);
-+
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_bit_depth.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_bit_depth.c
-new file mode 100644
-index 0000000..747f2c7
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_bit_depth.c
-@@ -0,0 +1,840 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/* include DCE11 register header files */
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "dce110_transform.h"
-+
-+#include "include/logger_interface.h"
-+#include "include/fixed32_32.h"
-+
-+#define DCP_REG(reg)\
-+ (reg + xfm110->offsets.dcp_offset)
-+
-+#define LB_REG(reg)\
-+ (reg + xfm110->offsets.lb_offset)
-+
-+#define LB_TOTAL_NUMBER_OF_ENTRIES 1712
-+#define LB_BITS_PER_ENTRY 144
-+
-+enum dcp_out_trunc_round_mode {
-+ DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE,
-+ DCP_OUT_TRUNC_ROUND_MODE_ROUND
-+};
-+
-+enum dcp_out_trunc_round_depth {
-+ DCP_OUT_TRUNC_ROUND_DEPTH_14BIT,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_13BIT,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_12BIT,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_11BIT,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_10BIT,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_9BIT,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_8BIT
-+};
-+
-+/* defines the various methods of bit reduction available for use */
-+enum dcp_bit_depth_reduction_mode {
-+ DCP_BIT_DEPTH_REDUCTION_MODE_DITHER,
-+ DCP_BIT_DEPTH_REDUCTION_MODE_ROUND,
-+ DCP_BIT_DEPTH_REDUCTION_MODE_TRUNCATE,
-+ DCP_BIT_DEPTH_REDUCTION_MODE_DISABLED,
-+ DCP_BIT_DEPTH_REDUCTION_MODE_INVALID
-+};
-+
-+enum dcp_spatial_dither_mode {
-+ DCP_SPATIAL_DITHER_MODE_AAAA,
-+ DCP_SPATIAL_DITHER_MODE_A_AA_A,
-+ DCP_SPATIAL_DITHER_MODE_AABBAABB,
-+ DCP_SPATIAL_DITHER_MODE_AABBCCAABBCC,
-+ DCP_SPATIAL_DITHER_MODE_INVALID
-+};
-+
-+enum dcp_spatial_dither_depth {
-+ DCP_SPATIAL_DITHER_DEPTH_30BPP,
-+ DCP_SPATIAL_DITHER_DEPTH_24BPP
-+};
-+
-+static bool set_clamp(
-+ struct dce110_transform *xfm110,
-+ enum dc_color_depth depth);
-+
-+static bool set_round(
-+ struct dce110_transform *xfm110,
-+ enum dcp_out_trunc_round_mode mode,
-+ enum dcp_out_trunc_round_depth depth);
-+
-+static bool set_dither(
-+ struct dce110_transform *xfm110,
-+ bool dither_enable,
-+ enum dcp_spatial_dither_mode dither_mode,
-+ enum dcp_spatial_dither_depth dither_depth,
-+ bool frame_random_enable,
-+ bool rgb_random_enable,
-+ bool highpass_random_enable);
-+
-+/**
-+ *******************************************************************************
-+ * dce110_transform_bit_depth_reduction_program
-+ *
-+ * @brief
-+ * Programs the DCP bit depth reduction registers (Clamp, Round/Truncate,
-+ * Dither) for dce110
-+ *
-+ * @param depth : bit depth to set the clamp to (should match denorm)
-+ *
-+ * @return
-+ * true if succeeds.
-+ *******************************************************************************
-+ */
-+static bool program_bit_depth_reduction(
-+ struct dce110_transform *xfm110,
-+ enum dc_color_depth depth)
-+{
-+ enum dcp_bit_depth_reduction_mode depth_reduction_mode;
-+ enum dcp_spatial_dither_mode spatial_dither_mode;
-+ bool frame_random_enable;
-+ bool rgb_random_enable;
-+ bool highpass_random_enable;
-+
-+ if (depth > COLOR_DEPTH_121212) {
-+ ASSERT_CRITICAL(false); /* Invalid clamp bit depth */
-+ return false;
-+ }
-+
-+ depth_reduction_mode = DCP_BIT_DEPTH_REDUCTION_MODE_DITHER;
-+
-+ spatial_dither_mode = DCP_SPATIAL_DITHER_MODE_A_AA_A;
-+
-+ frame_random_enable = true;
-+ rgb_random_enable = true;
-+ highpass_random_enable = true;
-+
-+ if (!set_clamp(xfm110, depth)) {
-+ /* Failure in set_clamp() */
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+ switch (depth_reduction_mode) {
-+ case DCP_BIT_DEPTH_REDUCTION_MODE_DITHER:
-+ /* Spatial Dither: Set round/truncate to bypass (12bit),
-+ * enable Dither (30bpp) */
-+ set_round(xfm110,
-+ DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_12BIT);
-+
-+ set_dither(xfm110, true, spatial_dither_mode,
-+ DCP_SPATIAL_DITHER_DEPTH_30BPP, frame_random_enable,
-+ rgb_random_enable, highpass_random_enable);
-+ break;
-+ case DCP_BIT_DEPTH_REDUCTION_MODE_ROUND:
-+ /* Round: Enable round (10bit), disable Dither */
-+ set_round(xfm110,
-+ DCP_OUT_TRUNC_ROUND_MODE_ROUND,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_10BIT);
-+
-+ set_dither(xfm110, false, spatial_dither_mode,
-+ DCP_SPATIAL_DITHER_DEPTH_30BPP, frame_random_enable,
-+ rgb_random_enable, highpass_random_enable);
-+ break;
-+ case DCP_BIT_DEPTH_REDUCTION_MODE_TRUNCATE: /* Truncate */
-+ /* Truncate: Enable truncate (10bit), disable Dither */
-+ set_round(xfm110,
-+ DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_10BIT);
-+
-+ set_dither(xfm110, false, spatial_dither_mode,
-+ DCP_SPATIAL_DITHER_DEPTH_30BPP, frame_random_enable,
-+ rgb_random_enable, highpass_random_enable);
-+ break;
-+
-+ case DCP_BIT_DEPTH_REDUCTION_MODE_DISABLED: /* Disabled */
-+ /* Truncate: Set round/truncate to bypass (12bit),
-+ * disable Dither */
-+ set_round(xfm110,
-+ DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_12BIT);
-+
-+ set_dither(xfm110, false, spatial_dither_mode,
-+ DCP_SPATIAL_DITHER_DEPTH_30BPP, frame_random_enable,
-+ rgb_random_enable, highpass_random_enable);
-+ break;
-+ default:
-+ /* Invalid DCP Depth reduction mode */
-+ ASSERT_CRITICAL(false);
-+ break;
-+ }
-+
-+ return true;
-+}
-+
-+/**
-+ *******************************************************************************
-+ * set_clamp
-+ *
-+ * @param depth : bit depth to set the clamp to (should match denorm)
-+ *
-+ * @brief
-+ * Programs clamp according to panel bit depth.
-+ *
-+ * @return
-+ * true if succeeds
-+ *
-+ *******************************************************************************
-+ */
-+static bool set_clamp(
-+ struct dce110_transform *xfm110,
-+ enum dc_color_depth depth)
-+{
-+ uint32_t clamp_max = 0;
-+
-+ /* At the clamp block the data will be MSB aligned, so we set the max
-+ * clamp accordingly.
-+ * For example, the max value for 6 bits MSB aligned (14 bit bus) would
-+ * be "11 1111 0000 0000" in binary, so 0x3F00.
-+ */
-+ switch (depth) {
-+ case COLOR_DEPTH_666:
-+ /* 6bit MSB aligned on 14 bit bus '11 1111 0000 0000' */
-+ clamp_max = 0x3F00;
-+ break;
-+ case COLOR_DEPTH_888:
-+ /* 8bit MSB aligned on 14 bit bus '11 1111 1100 0000' */
-+ clamp_max = 0x3FC0;
-+ break;
-+ case COLOR_DEPTH_101010:
-+ /* 10bit MSB aligned on 14 bit bus '11 1111 1111 1100' */
-+ clamp_max = 0x3FFC;
-+ break;
-+ case COLOR_DEPTH_121212:
-+ /* 12bit MSB aligned on 14 bit bus '11 1111 1111 1111' */
-+ clamp_max = 0x3FFF;
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false); /* Invalid clamp bit depth */
-+ return false;
-+ }
-+
-+ {
-+ uint32_t value = 0;
-+ /* always set min to 0 */
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ OUT_CLAMP_CONTROL_B_CB,
-+ OUT_CLAMP_MIN_B_CB);
-+
-+ set_reg_field_value(
-+ value,
-+ clamp_max,
-+ OUT_CLAMP_CONTROL_B_CB,
-+ OUT_CLAMP_MAX_B_CB);
-+
-+ dal_write_reg(xfm110->base.ctx,
-+ DCP_REG(mmOUT_CLAMP_CONTROL_B_CB),
-+ value);
-+ }
-+
-+ {
-+ uint32_t value = 0;
-+ /* always set min to 0 */
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ OUT_CLAMP_CONTROL_G_Y,
-+ OUT_CLAMP_MIN_G_Y);
-+
-+ set_reg_field_value(
-+ value,
-+ clamp_max,
-+ OUT_CLAMP_CONTROL_G_Y,
-+ OUT_CLAMP_MAX_G_Y);
-+
-+ dal_write_reg(xfm110->base.ctx,
-+ DCP_REG(mmOUT_CLAMP_CONTROL_G_Y),
-+ value);
-+ }
-+
-+ {
-+ uint32_t value = 0;
-+ /* always set min to 0 */
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ OUT_CLAMP_CONTROL_R_CR,
-+ OUT_CLAMP_MIN_R_CR);
-+
-+ set_reg_field_value(
-+ value,
-+ clamp_max,
-+ OUT_CLAMP_CONTROL_R_CR,
-+ OUT_CLAMP_MAX_R_CR);
-+
-+ dal_write_reg(xfm110->base.ctx,
-+ DCP_REG(mmOUT_CLAMP_CONTROL_R_CR),
-+ value);
-+ }
-+
-+ return true;
-+}
-+
-+/**
-+ *******************************************************************************
-+ * set_round
-+ *
-+ * @brief
-+ * Programs Round/Truncate
-+ *
-+ * @param [in] mode :round or truncate
-+ * @param [in] depth :bit depth to round/truncate to
-+ OUT_ROUND_TRUNC_MODE 3:0 0xA Output data round or truncate mode
-+ POSSIBLE VALUES:
-+ 00 - truncate to u0.12
-+ 01 - truncate to u0.11
-+ 02 - truncate to u0.10
-+ 03 - truncate to u0.9
-+ 04 - truncate to u0.8
-+ 05 - reserved
-+ 06 - truncate to u0.14
-+ 07 - truncate to u0.13 set_reg_field_value(
-+ value,
-+ clamp_max,
-+ OUT_CLAMP_CONTROL_R_CR,
-+ OUT_CLAMP_MAX_R_CR);
-+ 08 - round to u0.12
-+ 09 - round to u0.11
-+ 10 - round to u0.10
-+ 11 - round to u0.9
-+ 12 - round to u0.8
-+ 13 - reserved
-+ 14 - round to u0.14
-+ 15 - round to u0.13
-+
-+ * @return
-+ * true if succeeds.
-+ *******************************************************************************
-+ */
-+static bool set_round(
-+ struct dce110_transform *xfm110,
-+ enum dcp_out_trunc_round_mode mode,
-+ enum dcp_out_trunc_round_depth depth)
-+{
-+ uint32_t depth_bits = 0;
-+ uint32_t mode_bit = 0;
-+ /* zero out all bits */
-+ uint32_t value = 0;
-+
-+ /* set up bit depth */
-+ switch (depth) {
-+ case DCP_OUT_TRUNC_ROUND_DEPTH_14BIT:
-+ depth_bits = 6;
-+ break;
-+ case DCP_OUT_TRUNC_ROUND_DEPTH_13BIT:
-+ depth_bits = 7;
-+ break;
-+ case DCP_OUT_TRUNC_ROUND_DEPTH_12BIT:
-+ depth_bits = 0;
-+ break;
-+ case DCP_OUT_TRUNC_ROUND_DEPTH_11BIT:
-+ depth_bits = 1;
-+ break;
-+ case DCP_OUT_TRUNC_ROUND_DEPTH_10BIT:
-+ depth_bits = 2;
-+ break;
-+ case DCP_OUT_TRUNC_ROUND_DEPTH_9BIT:
-+ depth_bits = 3;
-+ break;
-+ case DCP_OUT_TRUNC_ROUND_DEPTH_8BIT:
-+ depth_bits = 4;
-+ break;
-+ default:
-+ /* Invalid dcp_out_trunc_round_depth */
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ set_reg_field_value(
-+ value,
-+ depth_bits,
-+ OUT_ROUND_CONTROL,
-+ OUT_ROUND_TRUNC_MODE);
-+
-+ /* set up round or truncate */
-+ switch (mode) {
-+ case DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE:
-+ mode_bit = 0;
-+ break;
-+ case DCP_OUT_TRUNC_ROUND_MODE_ROUND:
-+ mode_bit = 1;
-+ break;
-+ default:
-+ /* Invalid dcp_out_trunc_round_mode */
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ depth_bits |= mode_bit << 3;
-+
-+ set_reg_field_value(
-+ value,
-+ depth_bits,
-+ OUT_ROUND_CONTROL,
-+ OUT_ROUND_TRUNC_MODE);
-+
-+ /* write the register */
-+ dal_write_reg(xfm110->base.ctx,
-+ DCP_REG(mmOUT_ROUND_CONTROL),
-+ value);
-+
-+ return true;
-+}
-+
-+/**
-+ *******************************************************************************
-+ * set_dither
-+ *
-+ * @brief
-+ * Programs Dither
-+ *
-+ * @param [in] dither_enable : enable dither
-+ * @param [in] dither_mode : dither mode to set
-+ * @param [in] dither_depth : bit depth to dither to
-+ * @param [in] frame_random_enable : enable frame random
-+ * @param [in] rgb_random_enable : enable rgb random
-+ * @param [in] highpass_random_enable : enable highpass random
-+ *
-+ * @return
-+ * true if succeeds.
-+ *******************************************************************************
-+ */
-+
-+static bool set_dither(
-+ struct dce110_transform *xfm110,
-+ bool dither_enable,
-+ enum dcp_spatial_dither_mode dither_mode,
-+ enum dcp_spatial_dither_depth dither_depth,
-+ bool frame_random_enable,
-+ bool rgb_random_enable,
-+ bool highpass_random_enable)
-+{
-+ uint32_t dither_depth_bits = 0;
-+ uint32_t dither_mode_bits = 0;
-+ /* zero out all bits */
-+ uint32_t value = 0;
-+
-+ /* set up the fields */
-+ if (dither_enable)
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DCP_SPATIAL_DITHER_CNTL,
-+ DCP_SPATIAL_DITHER_EN);
-+
-+ switch (dither_mode) {
-+ case DCP_SPATIAL_DITHER_MODE_AAAA:
-+ dither_mode_bits = 0;
-+ break;
-+ case DCP_SPATIAL_DITHER_MODE_A_AA_A:
-+ dither_mode_bits = 1;
-+ break;
-+ case DCP_SPATIAL_DITHER_MODE_AABBAABB:
-+ dither_mode_bits = 2;
-+ break;
-+ case DCP_SPATIAL_DITHER_MODE_AABBCCAABBCC:
-+ dither_mode_bits = 3;
-+ break;
-+ default:
-+ /* Invalid dcp_spatial_dither_mode */
-+ ASSERT_CRITICAL(false);
-+ return false;
-+
-+ }
-+ set_reg_field_value(
-+ value,
-+ dither_mode_bits,
-+ DCP_SPATIAL_DITHER_CNTL,
-+ DCP_SPATIAL_DITHER_MODE);
-+
-+ switch (dither_depth) {
-+ case DCP_SPATIAL_DITHER_DEPTH_30BPP:
-+ dither_depth_bits = 0;
-+ break;
-+ case DCP_SPATIAL_DITHER_DEPTH_24BPP:
-+ dither_depth_bits = 1;
-+ break;
-+ default:
-+ /* Invalid dcp_spatial_dither_depth */
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ set_reg_field_value(
-+ value,
-+ dither_depth_bits,
-+ DCP_SPATIAL_DITHER_CNTL,
-+ DCP_SPATIAL_DITHER_DEPTH);
-+
-+ if (frame_random_enable)
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DCP_SPATIAL_DITHER_CNTL,
-+ DCP_FRAME_RANDOM_ENABLE);
-+
-+ if (rgb_random_enable)
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DCP_SPATIAL_DITHER_CNTL,
-+ DCP_RGB_RANDOM_ENABLE);
-+
-+ if (highpass_random_enable)
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DCP_SPATIAL_DITHER_CNTL,
-+ DCP_HIGHPASS_RANDOM_ENABLE);
-+
-+ /* write the register */
-+ dal_write_reg(xfm110->base.ctx,
-+ DCP_REG(mmDCP_SPATIAL_DITHER_CNTL),
-+ value);
-+
-+ return true;
-+}
-+
-+bool dce110_transform_get_max_num_of_supported_lines(
-+ struct dce110_transform *xfm110,
-+ enum lb_pixel_depth depth,
-+ uint32_t pixel_width,
-+ uint32_t *lines)
-+{
-+ uint32_t pixels_per_entries = 0;
-+ uint32_t max_pixels_supports = 0;
-+
-+ if (pixel_width == 0)
-+ return false;
-+
-+ /* Find number of pixels that can fit into a single LB entry and
-+ * take floor of the value since we cannot store a single pixel
-+ * across multiple entries. */
-+ switch (depth) {
-+ case LB_PIXEL_DEPTH_18BPP:
-+ pixels_per_entries = LB_BITS_PER_ENTRY / 18;
-+ break;
-+
-+ case LB_PIXEL_DEPTH_24BPP:
-+ pixels_per_entries = LB_BITS_PER_ENTRY / 24;
-+ break;
-+
-+ case LB_PIXEL_DEPTH_30BPP:
-+ pixels_per_entries = LB_BITS_PER_ENTRY / 30;
-+ break;
-+
-+ case LB_PIXEL_DEPTH_36BPP:
-+ pixels_per_entries = LB_BITS_PER_ENTRY / 36;
-+ break;
-+
-+ default:
-+ dal_logger_write(xfm110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s: Invalid LB pixel depth",
-+ __func__);
-+ break;
-+ }
-+
-+ if (pixels_per_entries == 0)
-+ return false;
-+
-+ max_pixels_supports = pixels_per_entries * LB_TOTAL_NUMBER_OF_ENTRIES;
-+
-+ *lines = max_pixels_supports / pixel_width;
-+ return true;
-+}
-+
-+void dce110_transform_enable_alpha(
-+ struct dce110_transform *xfm110,
-+ bool enable)
-+{
-+ struct dc_context *ctx = xfm110->base.ctx;
-+ uint32_t value;
-+ uint32_t addr = LB_REG(mmLB_DATA_FORMAT);
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ if (enable == 1)
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ LB_DATA_FORMAT,
-+ ALPHA_EN);
-+ else
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ LB_DATA_FORMAT,
-+ ALPHA_EN);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+static enum lb_pixel_depth translate_display_bpp_to_lb_depth(
-+ uint32_t display_bpp)
-+{
-+ switch (display_bpp) {
-+ case 18:
-+ return LB_PIXEL_DEPTH_18BPP;
-+ case 24:
-+ return LB_PIXEL_DEPTH_24BPP;
-+ case 36:
-+ case 42:
-+ case 48:
-+ return LB_PIXEL_DEPTH_36BPP;
-+ case 30:
-+ default:
-+ return LB_PIXEL_DEPTH_30BPP;
-+ }
-+}
-+
-+bool dce110_transform_get_next_lower_pixel_storage_depth(
-+ struct dce110_transform *xfm110,
-+ uint32_t display_bpp,
-+ enum lb_pixel_depth depth,
-+ enum lb_pixel_depth *lower_depth)
-+{
-+ enum lb_pixel_depth depth_req_by_display =
-+ translate_display_bpp_to_lb_depth(display_bpp);
-+ uint32_t current_required_depth = depth_req_by_display;
-+ uint32_t current_depth = depth;
-+
-+ /* if required display depth < current we could go down, for example
-+ * from LB_PIXEL_DEPTH_30BPP to LB_PIXEL_DEPTH_24BPP
-+ */
-+ if (current_required_depth < current_depth) {
-+ current_depth = current_depth >> 1;
-+ if (xfm110->lb_pixel_depth_supported & current_depth) {
-+ *lower_depth = current_depth;
-+ return true;
-+ }
-+ }
-+ return false;
-+}
-+
-+bool dce110_transform_is_prefetch_enabled(
-+ struct dce110_transform *xfm110)
-+{
-+ uint32_t value = dal_read_reg(
-+ xfm110->base.ctx, LB_REG(mmLB_DATA_FORMAT));
-+
-+ if (get_reg_field_value(value, LB_DATA_FORMAT, PREFETCH) == 1)
-+ return true;
-+
-+ return false;
-+}
-+
-+bool dce110_transform_get_current_pixel_storage_depth(
-+ struct transform *xfm,
-+ enum lb_pixel_depth *depth)
-+{
-+ struct dce110_transform *xfm110 = TO_DCE110_TRANSFORM(xfm);
-+ uint32_t value = 0;
-+
-+ if (depth == NULL)
-+ return false;
-+
-+ value = dal_read_reg(
-+ xfm->ctx,
-+ LB_REG(mmLB_DATA_FORMAT));
-+
-+ switch (get_reg_field_value(value, LB_DATA_FORMAT, PIXEL_DEPTH)) {
-+ case 0:
-+ *depth = LB_PIXEL_DEPTH_30BPP;
-+ break;
-+ case 1:
-+ *depth = LB_PIXEL_DEPTH_24BPP;
-+ break;
-+ case 2:
-+ *depth = LB_PIXEL_DEPTH_18BPP;
-+ break;
-+ case 3:
-+ *depth = LB_PIXEL_DEPTH_36BPP;
-+ break;
-+ default:
-+ dal_logger_write(xfm->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s: Invalid LB pixel depth",
-+ __func__);
-+ *depth = LB_PIXEL_DEPTH_30BPP;
-+ break;
-+ }
-+ return true;
-+
-+}
-+
-+static void set_denormalization(
-+ struct dce110_transform *xfm110,
-+ enum dc_color_depth depth)
-+{
-+ uint32_t value = dal_read_reg(xfm110->base.ctx,
-+ DCP_REG(mmDENORM_CONTROL));
-+
-+ switch (depth) {
-+ case COLOR_DEPTH_666:
-+ /* 63/64 for 6 bit output color depth */
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DENORM_CONTROL,
-+ DENORM_MODE);
-+ break;
-+ case COLOR_DEPTH_888:
-+ /* Unity for 8 bit output color depth
-+ * because prescale is disabled by default */
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DENORM_CONTROL,
-+ DENORM_MODE);
-+ break;
-+ case COLOR_DEPTH_101010:
-+ /* 1023/1024 for 10 bit output color depth */
-+ set_reg_field_value(
-+ value,
-+ 3,
-+ DENORM_CONTROL,
-+ DENORM_MODE);
-+ break;
-+ case COLOR_DEPTH_121212:
-+ /* 4095/4096 for 12 bit output color depth */
-+ set_reg_field_value(
-+ value,
-+ 5,
-+ DENORM_CONTROL,
-+ DENORM_MODE);
-+ break;
-+ case COLOR_DEPTH_141414:
-+ case COLOR_DEPTH_161616:
-+ default:
-+ /* not valid used case! */
-+ break;
-+ }
-+
-+ dal_write_reg(xfm110->base.ctx,
-+ DCP_REG(mmDENORM_CONTROL),
-+ value);
-+
-+}
-+
-+bool dce110_transform_set_pixel_storage_depth(
-+ struct transform *xfm,
-+ enum lb_pixel_depth depth)
-+{
-+ struct dce110_transform *xfm110 = TO_DCE110_TRANSFORM(xfm);
-+ bool ret = true;
-+ uint32_t value;
-+ enum dc_color_depth color_depth;
-+
-+ value = dal_read_reg(
-+ xfm->ctx,
-+ LB_REG(mmLB_DATA_FORMAT));
-+ switch (depth) {
-+ case LB_PIXEL_DEPTH_18BPP:
-+ color_depth = COLOR_DEPTH_666;
-+ set_reg_field_value(value, 2, LB_DATA_FORMAT, PIXEL_DEPTH);
-+ set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE);
-+ break;
-+ case LB_PIXEL_DEPTH_24BPP:
-+ color_depth = COLOR_DEPTH_888;
-+ set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_DEPTH);
-+ set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE);
-+ break;
-+ case LB_PIXEL_DEPTH_30BPP:
-+ color_depth = COLOR_DEPTH_101010;
-+ set_reg_field_value(value, 0, LB_DATA_FORMAT, PIXEL_DEPTH);
-+ set_reg_field_value(value, 1, LB_DATA_FORMAT, PIXEL_EXPAN_MODE);
-+ break;
-+ case LB_PIXEL_DEPTH_36BPP:
-+ color_depth = COLOR_DEPTH_121212;
-+ set_reg_field_value(value, 3, LB_DATA_FORMAT, PIXEL_DEPTH);
-+ set_reg_field_value(value, 0, LB_DATA_FORMAT, PIXEL_EXPAN_MODE);
-+ break;
-+ default:
-+ ret = false;
-+ break;
-+ }
-+
-+ if (ret == true) {
-+ set_denormalization(xfm110, color_depth);
-+ ret = program_bit_depth_reduction(xfm110, color_depth);
-+
-+ set_reg_field_value(value, 0, LB_DATA_FORMAT, ALPHA_EN);
-+ dal_write_reg(
-+ xfm->ctx, LB_REG(mmLB_DATA_FORMAT), value);
-+ if (!(xfm110->lb_pixel_depth_supported & depth)) {
-+ /*we should use unsupported capabilities
-+ * unless it is required by w/a*/
-+ dal_logger_write(xfm->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s: Capability not supported",
-+ __func__);
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+/* LB_MEMORY_CONFIG
-+ * 00 - Use all three pieces of memory
-+ * 01 - Use only one piece of memory of total 720x144 bits
-+ * 10 - Use two pieces of memory of total 960x144 bits
-+ * 11 - reserved
-+ *
-+ * LB_MEMORY_SIZE
-+ * Total entries of LB memory.
-+ * This number should be larger than 960. The default value is 1712(0x6B0) */
-+bool dce110_transform_power_up_line_buffer(struct transform *xfm)
-+{
-+ struct dce110_transform *xfm110 = TO_DCE110_TRANSFORM(xfm);
-+ uint32_t value;
-+
-+ value = dal_read_reg(xfm110->base.ctx, LB_REG(mmLB_MEMORY_CTRL));
-+
-+ /*Use all three pieces of memory always*/
-+ set_reg_field_value(value, 0, LB_MEMORY_CTRL, LB_MEMORY_CONFIG);
-+ /*hard coded number DCE11 1712(0x6B0) Partitions: 720/960/1712*/
-+ set_reg_field_value(value, LB_TOTAL_NUMBER_OF_ENTRIES, LB_MEMORY_CTRL,
-+ LB_MEMORY_SIZE);
-+
-+ dal_write_reg(xfm110->base.ctx, LB_REG(mmLB_MEMORY_CTRL), value);
-+
-+ return true;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_bit_depth.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_bit_depth.h
-new file mode 100644
-index 0000000..ff100cc
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_bit_depth.h
-@@ -0,0 +1,51 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_TRANSFORM_BIT_DEPTH_DCE110_H__
-+#define __DC_TRANSFORM_BIT_DEPTH_DCE110_H__
-+
-+#include "dce110_transform.h"
-+
-+bool dce110_transform_power_up_line_buffer(struct transform *xfm);
-+
-+bool dce110_transform_get_max_num_of_supported_lines(
-+ struct dce110_transform *xfm110,
-+ enum lb_pixel_depth depth,
-+ uint32_t pixel_width,
-+ uint32_t *lines);
-+
-+void dce110_transform_enable_alpha(
-+ struct dce110_transform *xfm110,
-+ bool enable);
-+
-+bool dce110_transform_get_next_lower_pixel_storage_depth(
-+ struct dce110_transform *xfm110,
-+ uint32_t display_bpp,
-+ enum lb_pixel_depth depth,
-+ enum lb_pixel_depth *lower_depth);
-+
-+bool dce110_transform_is_prefetch_enabled(
-+ struct dce110_transform *xfm110);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_gamut.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_gamut.c
-new file mode 100644
-index 0000000..a5b5b01
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_gamut.c
-@@ -0,0 +1,297 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "dce110_transform.h"
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+#include "include/fixed31_32.h"
-+#include "include/hw_sequencer_types.h"
-+#include "basics/conversion.h"
-+#include "include/grph_object_id.h"
-+
-+enum {
-+ GAMUT_MATRIX_SIZE = 12
-+};
-+
-+#define DCP_REG(reg)\
-+ (reg + xfm110->offsets.dcp_offset)
-+
-+#define DISP_BRIGHTNESS_DEFAULT_HW 0
-+#define DISP_BRIGHTNESS_MIN_HW -25
-+#define DISP_BRIGHTNESS_MAX_HW 25
-+#define DISP_BRIGHTNESS_STEP_HW 1
-+#define DISP_BRIGHTNESS_HW_DIVIDER 100
-+
-+#define DISP_HUE_DEFAULT_HW 0
-+#define DISP_HUE_MIN_HW -30
-+#define DISP_HUE_MAX_HW 30
-+#define DISP_HUE_STEP_HW 1
-+#define DISP_HUE_HW_DIVIDER 1
-+
-+#define DISP_CONTRAST_DEFAULT_HW 100
-+#define DISP_CONTRAST_MIN_HW 50
-+#define DISP_CONTRAST_MAX_HW 150
-+#define DISP_CONTRAST_STEP_HW 1
-+#define DISP_CONTRAST_HW_DIVIDER 100
-+
-+#define DISP_SATURATION_DEFAULT_HW 100
-+#define DISP_SATURATION_MIN_HW 0
-+#define DISP_SATURATION_MAX_HW 200
-+#define DISP_SATURATION_STEP_HW 1
-+#define DISP_SATURATION_HW_DIVIDER 100
-+
-+#define DISP_KELVIN_DEGRES_DEFAULT 6500
-+#define DISP_KELVIN_DEGRES_MIN 4000
-+#define DISP_KELVIN_DEGRES_MAX 10000
-+#define DISP_KELVIN_DEGRES_STEP 100
-+#define DISP_KELVIN_HW_DIVIDER 10000
-+
-+static void program_gamut_remap(
-+ struct dce110_transform *xfm110,
-+ const uint16_t *reg_val)
-+{
-+ struct dc_context *ctx = xfm110->base.ctx;
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmGAMUT_REMAP_CONTROL);
-+
-+ /* the register controls ovl also */
-+ value = dal_read_reg(ctx, addr);
-+
-+ if (reg_val) {
-+ {
-+ uint32_t reg_data = 0;
-+ uint32_t addr = DCP_REG(mmGAMUT_REMAP_C11_C12);
-+
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ reg_data,
-+ reg_val[0],
-+ GAMUT_REMAP_C11_C12,
-+ GAMUT_REMAP_C11);
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ reg_data,
-+ reg_val[1],
-+ GAMUT_REMAP_C11_C12,
-+ GAMUT_REMAP_C12);
-+
-+ dal_write_reg(ctx, addr, reg_data);
-+ }
-+ {
-+ uint32_t reg_data = 0;
-+ uint32_t addr = DCP_REG(mmGAMUT_REMAP_C13_C14);
-+
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ reg_data,
-+ reg_val[2],
-+ GAMUT_REMAP_C13_C14,
-+ GAMUT_REMAP_C13);
-+
-+ /* fixed S0.13 format */
-+ set_reg_field_value(
-+ reg_data,
-+ reg_val[3],
-+ GAMUT_REMAP_C13_C14,
-+ GAMUT_REMAP_C14);
-+
-+ dal_write_reg(ctx, addr, reg_data);
-+ }
-+ {
-+ uint32_t reg_data = 0;
-+ uint32_t addr = DCP_REG(mmGAMUT_REMAP_C21_C22);
-+
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ reg_data,
-+ reg_val[4],
-+ GAMUT_REMAP_C21_C22,
-+ GAMUT_REMAP_C21);
-+
-+ /* fixed S0.13 format */
-+ set_reg_field_value(
-+ reg_data,
-+ reg_val[5],
-+ GAMUT_REMAP_C21_C22,
-+ GAMUT_REMAP_C22);
-+
-+ dal_write_reg(ctx, addr, reg_data);
-+ }
-+ {
-+ uint32_t reg_data = 0;
-+ uint32_t addr = DCP_REG(mmGAMUT_REMAP_C23_C24);
-+
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ reg_data,
-+ reg_val[6],
-+ GAMUT_REMAP_C23_C24,
-+ GAMUT_REMAP_C23);
-+
-+ /* fixed S0.13 format */
-+ set_reg_field_value(
-+ reg_data,
-+ reg_val[7],
-+ GAMUT_REMAP_C23_C24,
-+ GAMUT_REMAP_C24);
-+
-+ dal_write_reg(ctx, addr, reg_data);
-+ }
-+ {
-+ uint32_t reg_data = 0;
-+ uint32_t addr = DCP_REG(mmGAMUT_REMAP_C31_C32);
-+
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ reg_data,
-+ reg_val[8],
-+ GAMUT_REMAP_C31_C32,
-+ GAMUT_REMAP_C31);
-+
-+ /* fixed S0.13 format */
-+ set_reg_field_value(
-+ reg_data,
-+ reg_val[9],
-+ GAMUT_REMAP_C31_C32,
-+ GAMUT_REMAP_C32);
-+
-+ dal_write_reg(ctx, addr, reg_data);
-+ }
-+ {
-+ uint32_t reg_data = 0;
-+ uint32_t addr = DCP_REG(mmGAMUT_REMAP_C33_C34);
-+
-+ /* fixed S2.13 format */
-+ set_reg_field_value(
-+ reg_data,
-+ reg_val[10],
-+ GAMUT_REMAP_C33_C34,
-+ GAMUT_REMAP_C33);
-+
-+ /* fixed S0.13 format */
-+ set_reg_field_value(
-+ reg_data,
-+ reg_val[11],
-+ GAMUT_REMAP_C33_C34,
-+ GAMUT_REMAP_C34);
-+
-+ dal_write_reg(ctx, addr, reg_data);
-+ }
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ GAMUT_REMAP_CONTROL,
-+ GRPH_GAMUT_REMAP_MODE);
-+
-+ } else
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ GAMUT_REMAP_CONTROL,
-+ GRPH_GAMUT_REMAP_MODE);
-+
-+ addr = DCP_REG(mmGAMUT_REMAP_CONTROL);
-+ dal_write_reg(ctx, addr, value);
-+
-+}
-+
-+/**
-+ *****************************************************************************
-+ * Function: dal_transform_wide_gamut_set_gamut_remap
-+ *
-+ * @param [in] const struct grph_csc_adjustment *adjust
-+ *
-+ * @return
-+ * void
-+ *
-+ * @note calculate and apply color temperature adjustment to in Rgb color space
-+ *
-+ * @see
-+ *
-+ *****************************************************************************
-+ */
-+void dce110_transform_set_gamut_remap(
-+ struct transform *xfm,
-+ const struct grph_csc_adjustment *adjust)
-+{
-+ struct dce110_transform *xfm110 = TO_DCE110_TRANSFORM(xfm);
-+
-+ if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW ||
-+ adjust->temperature_divider == 0)
-+ program_gamut_remap(xfm110, NULL);
-+ else {
-+ struct fixed31_32 arr_matrix[GAMUT_MATRIX_SIZE];
-+ uint16_t arr_reg_val[GAMUT_MATRIX_SIZE];
-+
-+ arr_matrix[0] =
-+ dal_fixed31_32_from_fraction(
-+ adjust->temperature_matrix[0],
-+ adjust->temperature_divider);
-+ arr_matrix[1] =
-+ dal_fixed31_32_from_fraction(
-+ adjust->temperature_matrix[1],
-+ adjust->temperature_divider);
-+ arr_matrix[2] =
-+ dal_fixed31_32_from_fraction(
-+ adjust->temperature_matrix[2],
-+ adjust->temperature_divider);
-+ arr_matrix[3] = dal_fixed31_32_zero;
-+
-+ arr_matrix[4] =
-+ dal_fixed31_32_from_fraction(
-+ adjust->temperature_matrix[3],
-+ adjust->temperature_divider);
-+ arr_matrix[5] =
-+ dal_fixed31_32_from_fraction(
-+ adjust->temperature_matrix[4],
-+ adjust->temperature_divider);
-+ arr_matrix[6] =
-+ dal_fixed31_32_from_fraction(
-+ adjust->temperature_matrix[5],
-+ adjust->temperature_divider);
-+ arr_matrix[7] = dal_fixed31_32_zero;
-+
-+ arr_matrix[8] =
-+ dal_fixed31_32_from_fraction(
-+ adjust->temperature_matrix[6],
-+ adjust->temperature_divider);
-+ arr_matrix[9] =
-+ dal_fixed31_32_from_fraction(
-+ adjust->temperature_matrix[7],
-+ adjust->temperature_divider);
-+ arr_matrix[10] =
-+ dal_fixed31_32_from_fraction(
-+ adjust->temperature_matrix[8],
-+ adjust->temperature_divider);
-+ arr_matrix[11] = dal_fixed31_32_zero;
-+
-+ convert_float_matrix(
-+ arr_reg_val, arr_matrix, GAMUT_MATRIX_SIZE);
-+
-+ program_gamut_remap(xfm110, arr_reg_val);
-+ }
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_scl.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_scl.c
-new file mode 100644
-index 0000000..f313d2c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_scl.c
-@@ -0,0 +1,818 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/* include DCE11 register header files */
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "dce110_transform.h"
-+
-+#define UP_SCALER_RATIO_MAX 16000
-+#define DOWN_SCALER_RATIO_MAX 250
-+#define SCALER_RATIO_DIVIDER 1000
-+
-+#define SCL_REG(reg)\
-+ (reg + xfm110->offsets.scl_offset)
-+
-+#define DCFE_REG(reg)\
-+ (reg + xfm110->offsets.dcfe_offset)
-+
-+static void disable_enhanced_sharpness(struct dce110_transform *xfm110)
-+{
-+ uint32_t value;
-+
-+ value = dal_read_reg(xfm110->base.ctx,
-+ SCL_REG(mmSCL_F_SHARP_CONTROL));
-+
-+ set_reg_field_value(value, 0,
-+ SCL_F_SHARP_CONTROL, SCL_HF_SHARP_EN);
-+
-+ set_reg_field_value(value, 0,
-+ SCL_F_SHARP_CONTROL, SCL_VF_SHARP_EN);
-+
-+ set_reg_field_value(value, 0,
-+ SCL_F_SHARP_CONTROL, SCL_HF_SHARP_SCALE_FACTOR);
-+
-+ set_reg_field_value(value, 0,
-+ SCL_F_SHARP_CONTROL, SCL_VF_SHARP_SCALE_FACTOR);
-+
-+ dal_write_reg(xfm110->base.ctx,
-+ SCL_REG(mmSCL_F_SHARP_CONTROL), value);
-+}
-+
-+/**
-+* Function:
-+* void setup_scaling_configuration
-+*
-+* Purpose: setup scaling mode : bypass, RGb, YCbCr and nummber of taps
-+* Input: data
-+*
-+* Output:
-+ void
-+*/
-+static bool setup_scaling_configuration(
-+ struct dce110_transform *xfm110,
-+ const struct scaler_data *data)
-+{
-+ struct dc_context *ctx = xfm110->base.ctx;
-+ uint32_t addr;
-+ uint32_t value;
-+
-+ if (data->taps.h_taps + data->taps.v_taps <= 2) {
-+ dce110_transform_set_scaler_bypass(&xfm110->base);
-+ return false;
-+ }
-+
-+ {
-+ addr = SCL_REG(mmSCL_MODE);
-+ value = dal_read_reg(ctx, addr);
-+
-+ if (data->dal_pixel_format <= PIXEL_FORMAT_GRPH_END)
-+ set_reg_field_value(value, 1, SCL_MODE, SCL_MODE);
-+ else
-+ set_reg_field_value(value, 2, SCL_MODE, SCL_MODE);
-+
-+ set_reg_field_value(value, 1, SCL_MODE, SCL_PSCL_EN);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+ {
-+ addr = SCL_REG(mmSCL_TAP_CONTROL);
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(value, data->taps.h_taps - 1,
-+ SCL_TAP_CONTROL, SCL_H_NUM_OF_TAPS);
-+
-+ set_reg_field_value(value, data->taps.v_taps - 1,
-+ SCL_TAP_CONTROL, SCL_V_NUM_OF_TAPS);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+ {
-+ addr = SCL_REG(mmSCL_CONTROL);
-+ value = dal_read_reg(ctx, addr);
-+ /* 1 - Replaced out of bound pixels with edge */
-+ set_reg_field_value(value, 1, SCL_CONTROL, SCL_BOUNDARY_MODE);
-+
-+ /* 1 - Replaced out of bound pixels with the edge pixel. */
-+ dal_write_reg(ctx, addr, value);
-+ }
-+
-+ return true;
-+}
-+
-+/**
-+* Function:
-+* void program_overscan
-+*
-+* Purpose: Programs overscan border
-+* Input: overscan
-+*
-+* Output:
-+ void
-+*/
-+static void program_overscan(
-+ struct dce110_transform *xfm110,
-+ const struct overscan_info *overscan)
-+{
-+ uint32_t overscan_left_right = 0;
-+ uint32_t overscan_top_bottom = 0;
-+
-+ set_reg_field_value(overscan_left_right, overscan->left,
-+ EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_LEFT);
-+
-+ set_reg_field_value(overscan_left_right, overscan->right,
-+ EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_RIGHT);
-+
-+ set_reg_field_value(overscan_top_bottom, overscan->top,
-+ EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_TOP);
-+
-+ set_reg_field_value(overscan_top_bottom, overscan->bottom,
-+ EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_BOTTOM);
-+
-+ dal_write_reg(xfm110->base.ctx,
-+ SCL_REG(mmEXT_OVERSCAN_LEFT_RIGHT),
-+ overscan_left_right);
-+
-+ dal_write_reg(xfm110->base.ctx,
-+ SCL_REG(mmEXT_OVERSCAN_TOP_BOTTOM),
-+ overscan_top_bottom);
-+}
-+
-+static void program_two_taps_filter(
-+ struct dce110_transform *xfm110,
-+ bool enable,
-+ bool vertical)
-+{
-+ uint32_t addr;
-+ uint32_t value;
-+ /* 1: Hard coded 2 tap filter
-+ * 0: Programmable 2 tap filter from coefficient RAM
-+ */
-+ if (vertical) {
-+ addr = SCL_REG(mmSCL_VERT_FILTER_CONTROL);
-+ value = dal_read_reg(xfm110->base.ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ enable ? 1 : 0,
-+ SCL_VERT_FILTER_CONTROL,
-+ SCL_V_2TAP_HARDCODE_COEF_EN);
-+
-+ } else {
-+ addr = SCL_REG(mmSCL_HORZ_FILTER_CONTROL);
-+ value = dal_read_reg(xfm110->base.ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ enable ? 1 : 0,
-+ SCL_HORZ_FILTER_CONTROL,
-+ SCL_H_2TAP_HARDCODE_COEF_EN);
-+ }
-+
-+ dal_write_reg(xfm110->base.ctx, addr, value);
-+}
-+
-+static void set_coeff_update_complete(struct dce110_transform *xfm110)
-+{
-+ uint32_t value;
-+ uint32_t addr = SCL_REG(mmSCL_UPDATE);
-+
-+ value = dal_read_reg(xfm110->base.ctx, addr);
-+ set_reg_field_value(value, 1,
-+ SCL_UPDATE, SCL_COEF_UPDATE_COMPLETE);
-+ dal_write_reg(xfm110->base.ctx, addr, value);
-+}
-+
-+static void program_filter(
-+ struct dce110_transform *xfm110,
-+ enum ram_filter_type filter_type,
-+ struct scaler_filter_params *scl_filter_params,
-+ uint32_t *coeffs,
-+ uint32_t coeffs_num)
-+{
-+ uint32_t phase = 0;
-+ uint32_t array_idx = 0;
-+ uint32_t pair = 0;
-+
-+ uint32_t taps_pairs = (scl_filter_params->taps + 1) / 2;
-+ uint32_t phases_to_program = scl_filter_params->phases / 2 + 1;
-+
-+ uint32_t i;
-+ uint32_t addr;
-+ uint32_t select_addr;
-+ uint32_t select;
-+ uint32_t data;
-+ /* We need to disable power gating on coeff memory to do programming */
-+
-+ uint32_t pwr_ctrl_orig;
-+ uint32_t pwr_ctrl_off;
-+
-+ addr = DCFE_REG(mmDCFE_MEM_PWR_CTRL);
-+ pwr_ctrl_orig = dal_read_reg(xfm110->base.ctx, addr);
-+ pwr_ctrl_off = pwr_ctrl_orig;
-+ set_reg_field_value(
-+ pwr_ctrl_off,
-+ 1,
-+ DCFE_MEM_PWR_CTRL,
-+ SCL_COEFF_MEM_PWR_DIS);
-+ dal_write_reg(xfm110->base.ctx, addr, pwr_ctrl_off);
-+
-+ addr = DCFE_REG(mmDCFE_MEM_PWR_STATUS);
-+ /* Wait to disable gating: */
-+ for (i = 0;
-+ i < 10 &&
-+ get_reg_field_value(
-+ dal_read_reg(xfm110->base.ctx, addr),
-+ DCFE_MEM_PWR_STATUS,
-+ SCL_COEFF_MEM_PWR_STATE);
-+ i++)
-+ dc_service_delay_in_microseconds(xfm110->base.ctx, 1);
-+
-+ ASSERT(i < 10);
-+
-+ select_addr = SCL_REG(mmSCL_COEF_RAM_SELECT);
-+ select = dal_read_reg(xfm110->base.ctx, select_addr);
-+
-+ set_reg_field_value(
-+ select,
-+ filter_type,
-+ SCL_COEF_RAM_SELECT,
-+ SCL_C_RAM_FILTER_TYPE);
-+ set_reg_field_value(
-+ select,
-+ 0,
-+ SCL_COEF_RAM_SELECT,
-+ SCL_C_RAM_TAP_PAIR_IDX);
-+ set_reg_field_value(
-+ select,
-+ 0,
-+ SCL_COEF_RAM_SELECT,
-+ SCL_C_RAM_PHASE);
-+
-+ data = 0;
-+
-+ for (phase = 0; phase < phases_to_program; phase++) {
-+ /* we always program N/2 + 1 phases, total phases N, but N/2-1
-+ * are just mirror phase 0 is unique and phase N/2 is unique
-+ * if N is even
-+ */
-+
-+ set_reg_field_value(
-+ select,
-+ phase,
-+ SCL_COEF_RAM_SELECT,
-+ SCL_C_RAM_PHASE);
-+
-+ for (pair = 0; pair < taps_pairs; pair++) {
-+ set_reg_field_value(
-+ select,
-+ pair,
-+ SCL_COEF_RAM_SELECT,
-+ SCL_C_RAM_TAP_PAIR_IDX);
-+ dal_write_reg(xfm110->base.ctx, select_addr, select);
-+
-+ /* even tap write enable */
-+ set_reg_field_value(
-+ data,
-+ 1,
-+ SCL_COEF_RAM_TAP_DATA,
-+ SCL_C_RAM_EVEN_TAP_COEF_EN);
-+ /* even tap data */
-+ set_reg_field_value(
-+ data,
-+ coeffs[array_idx],
-+ SCL_COEF_RAM_TAP_DATA,
-+ SCL_C_RAM_EVEN_TAP_COEF);
-+
-+ /* if we have odd number of taps and the last pair is
-+ * here then we do not need to program
-+ */
-+ if (scl_filter_params->taps % 2 &&
-+ pair == taps_pairs - 1) {
-+ /* odd tap write disable */
-+ set_reg_field_value(
-+ data,
-+ 0,
-+ SCL_COEF_RAM_TAP_DATA,
-+ SCL_C_RAM_ODD_TAP_COEF_EN);
-+ set_reg_field_value(
-+ data,
-+ 0,
-+ SCL_COEF_RAM_TAP_DATA,
-+ SCL_C_RAM_ODD_TAP_COEF);
-+ array_idx += 1;
-+ } else {
-+ /* odd tap write enable */
-+ set_reg_field_value(
-+ data,
-+ 1,
-+ SCL_COEF_RAM_TAP_DATA,
-+ SCL_C_RAM_ODD_TAP_COEF_EN);
-+ /* dbg_val: 0x1000 / sclFilterParams->taps; */
-+ set_reg_field_value(
-+ data,
-+ coeffs[array_idx + 1],
-+ SCL_COEF_RAM_TAP_DATA,
-+ SCL_C_RAM_ODD_TAP_COEF);
-+
-+ array_idx += 2;
-+ }
-+
-+ dal_write_reg(
-+ xfm110->base.ctx,
-+ SCL_REG(mmSCL_COEF_RAM_TAP_DATA),
-+ data);
-+ }
-+ }
-+
-+ ASSERT(coeffs_num == array_idx);
-+
-+ /* reset the power gating register */
-+ dal_write_reg(
-+ xfm110->base.ctx,
-+ DCFE_REG(mmDCFE_MEM_PWR_CTRL),
-+ pwr_ctrl_orig);
-+
-+ set_coeff_update_complete(xfm110);
-+}
-+
-+/*
-+ *
-+ * Populates an array with filter coefficients in 1.1.12 fixed point form
-+*/
-+static bool get_filter_coefficients(
-+ struct dce110_transform *xfm110,
-+ uint32_t taps,
-+ uint32_t **data_tab,
-+ uint32_t *data_size)
-+{
-+ uint32_t num = 0;
-+ uint32_t i;
-+ const struct fixed31_32 *filter =
-+ dal_scaler_filter_get(
-+ xfm110->base.filter,
-+ data_tab,
-+ &num);
-+ uint32_t *data_row;
-+
-+ if (!filter) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+ data_row = *data_tab;
-+
-+ for (i = 0; i < num; ++i) {
-+ /* req. format sign fixed 1.1.12, the values are always between
-+ * [-1; 1]
-+ *
-+ * Each phase is mirrored as follows :
-+ * 0 : Phase 0
-+ * 1 : Phase 1 or Phase 64 - 1 / 128 - 1
-+ * N : Phase N or Phase 64 - N / 128 - N
-+ *
-+ * Convert from Fixed31_32 to 1.1.12 by using floor on value
-+ * shifted by number of required fractional bits(12)
-+ */
-+ struct fixed31_32 value = filter[i];
-+
-+ data_row[i] =
-+ dal_fixed31_32_floor(dal_fixed31_32_shl(value, 12)) &
-+ 0x3FFC;
-+ }
-+ *data_size = num;
-+
-+ return true;
-+}
-+
-+static bool program_multi_taps_filter(
-+ struct dce110_transform *xfm110,
-+ const struct scaler_data *data,
-+ bool horizontal)
-+{
-+ struct scaler_filter_params filter_params;
-+ enum ram_filter_type filter_type;
-+ uint32_t src_size;
-+ uint32_t dst_size;
-+
-+ uint32_t *filter_data = NULL;
-+ uint32_t filter_data_size = 0;
-+
-+ /* 16 phases total for DCE11 */
-+ filter_params.phases = 16;
-+
-+ if (horizontal) {
-+ filter_params.taps = data->taps.h_taps;
-+ filter_params.sharpness = data->h_sharpness;
-+ filter_params.flags.bits.HORIZONTAL = 1;
-+
-+ src_size = data->viewport.width;
-+ dst_size =
-+ dal_fixed31_32_floor(
-+ dal_fixed31_32_div(
-+ dal_fixed31_32_from_int(
-+ data->viewport.width),
-+ data->ratios->horz));
-+
-+ filter_type = FILTER_TYPE_RGB_Y_HORIZONTAL;
-+ } else {
-+ filter_params.taps = data->taps.v_taps;
-+ filter_params.sharpness = data->v_sharpness;
-+ filter_params.flags.bits.HORIZONTAL = 0;
-+
-+ src_size = data->viewport.height;
-+ dst_size =
-+ dal_fixed31_32_floor(
-+ dal_fixed31_32_div(
-+ dal_fixed31_32_from_int(
-+ data->viewport.height),
-+ data->ratios->vert));
-+
-+ filter_type = FILTER_TYPE_RGB_Y_VERTICAL;
-+ }
-+
-+ /* 1. Generate the coefficients */
-+ if (!dal_scaler_filter_generate(
-+ xfm110->base.filter,
-+ &filter_params,
-+ src_size,
-+ dst_size))
-+ return false;
-+
-+ /* 2. Convert coefficients to fixed point format 1.12 (note coeff.
-+ * could be negative(!) and range is [ from -1 to 1 ]) */
-+ if (!get_filter_coefficients(
-+ xfm110,
-+ filter_params.taps,
-+ &filter_data,
-+ &filter_data_size))
-+ return false;
-+
-+ /* 3. Program the filter */
-+ program_filter(
-+ xfm110,
-+ filter_type,
-+ &filter_params,
-+ filter_data,
-+ filter_data_size);
-+
-+ /* 4. Program the alpha if necessary */
-+ if (data->flags.bits.SHOULD_PROGRAM_ALPHA) {
-+ if (horizontal)
-+ filter_type = FILTER_TYPE_ALPHA_HORIZONTAL;
-+ else
-+ filter_type = FILTER_TYPE_ALPHA_VERTICAL;
-+
-+ program_filter(
-+ xfm110,
-+ filter_type,
-+ &filter_params,
-+ filter_data,
-+ filter_data_size);
-+ }
-+
-+ return true;
-+}
-+
-+static void program_viewport(
-+ struct dce110_transform *xfm110,
-+ const struct rect *view_port)
-+{
-+ struct dc_context *ctx = xfm110->base.ctx;
-+ uint32_t value = 0;
-+ uint32_t addr = 0;
-+
-+ addr = SCL_REG(mmVIEWPORT_START);
-+ value = dal_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ view_port->x,
-+ VIEWPORT_START,
-+ VIEWPORT_X_START);
-+ set_reg_field_value(
-+ value,
-+ view_port->y,
-+ VIEWPORT_START,
-+ VIEWPORT_Y_START);
-+ dal_write_reg(ctx, addr, value);
-+
-+ addr = SCL_REG(mmVIEWPORT_SIZE);
-+ value = dal_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ view_port->height,
-+ VIEWPORT_SIZE,
-+ VIEWPORT_HEIGHT);
-+ set_reg_field_value(
-+ value,
-+ view_port->width,
-+ VIEWPORT_SIZE,
-+ VIEWPORT_WIDTH);
-+ dal_write_reg(ctx, addr, value);
-+
-+ /* TODO: add stereo support */
-+}
-+
-+static void calculate_inits(
-+ struct dce110_transform *xfm110,
-+ const struct scaler_data *data,
-+ struct scl_ratios_inits *inits)
-+{
-+ struct fixed31_32 h_init;
-+ struct fixed31_32 v_init;
-+ struct fixed31_32 v_init_bot;
-+
-+ inits->bottom_enable = 0;
-+ inits->h_int_scale_ratio =
-+ dal_fixed31_32_u2d19(data->ratios->horz) << 5;
-+ inits->v_int_scale_ratio =
-+ dal_fixed31_32_u2d19(data->ratios->vert) << 5;
-+
-+ h_init =
-+ dal_fixed31_32_div_int(
-+ dal_fixed31_32_add(
-+ data->ratios->horz,
-+ dal_fixed31_32_from_int(data->taps.h_taps + 1)),
-+ 2);
-+ inits->h_init.integer = dal_fixed31_32_floor(h_init);
-+ inits->h_init.fraction = dal_fixed31_32_u0d19(h_init) << 5;
-+
-+ v_init =
-+ dal_fixed31_32_div_int(
-+ dal_fixed31_32_add(
-+ data->ratios->vert,
-+ dal_fixed31_32_from_int(data->taps.v_taps + 1)),
-+ 2);
-+ inits->v_init.integer = dal_fixed31_32_floor(v_init);
-+ inits->v_init.fraction = dal_fixed31_32_u0d19(v_init) << 5;
-+
-+ if (data->flags.bits.INTERLACED) {
-+ v_init_bot =
-+ dal_fixed31_32_add(
-+ dal_fixed31_32_div_int(
-+ dal_fixed31_32_add(
-+ data->ratios->vert,
-+ dal_fixed31_32_from_int(
-+ data->taps.v_taps + 1)),
-+ 2),
-+ data->ratios->vert);
-+ inits->v_init_bottom.integer = dal_fixed31_32_floor(v_init_bot);
-+ inits->v_init_bottom.fraction =
-+ dal_fixed31_32_u0d19(v_init_bot) << 5;
-+
-+ inits->bottom_enable = 1;
-+ }
-+}
-+
-+static void program_scl_ratios_inits(
-+ struct dce110_transform *xfm110,
-+ struct scl_ratios_inits *inits)
-+{
-+ uint32_t addr = SCL_REG(mmSCL_HORZ_FILTER_SCALE_RATIO);
-+ uint32_t value = 0;
-+
-+ set_reg_field_value(
-+ value,
-+ inits->h_int_scale_ratio,
-+ SCL_HORZ_FILTER_SCALE_RATIO,
-+ SCL_H_SCALE_RATIO);
-+ dal_write_reg(xfm110->base.ctx, addr, value);
-+
-+ addr = SCL_REG(mmSCL_VERT_FILTER_SCALE_RATIO);
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ inits->v_int_scale_ratio,
-+ SCL_VERT_FILTER_SCALE_RATIO,
-+ SCL_V_SCALE_RATIO);
-+ dal_write_reg(xfm110->base.ctx, addr, value);
-+
-+ addr = SCL_REG(mmSCL_HORZ_FILTER_INIT);
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ inits->h_init.integer,
-+ SCL_HORZ_FILTER_INIT,
-+ SCL_H_INIT_INT);
-+ set_reg_field_value(
-+ value,
-+ inits->h_init.fraction,
-+ SCL_HORZ_FILTER_INIT,
-+ SCL_H_INIT_FRAC);
-+ dal_write_reg(xfm110->base.ctx, addr, value);
-+
-+ addr = SCL_REG(mmSCL_VERT_FILTER_INIT);
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ inits->v_init.integer,
-+ SCL_VERT_FILTER_INIT,
-+ SCL_V_INIT_INT);
-+ set_reg_field_value(
-+ value,
-+ inits->v_init.fraction,
-+ SCL_VERT_FILTER_INIT,
-+ SCL_V_INIT_FRAC);
-+ dal_write_reg(xfm110->base.ctx, addr, value);
-+
-+ if (inits->bottom_enable) {
-+ addr = SCL_REG(mmSCL_VERT_FILTER_INIT_BOT);
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ inits->v_init_bottom.integer,
-+ SCL_VERT_FILTER_INIT_BOT,
-+ SCL_V_INIT_INT_BOT);
-+ set_reg_field_value(
-+ value,
-+ inits->v_init_bottom.fraction,
-+ SCL_VERT_FILTER_INIT_BOT,
-+ SCL_V_INIT_FRAC_BOT);
-+ dal_write_reg(xfm110->base.ctx, addr, value);
-+ }
-+
-+ addr = SCL_REG(mmSCL_AUTOMATIC_MODE_CONTROL);
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ SCL_AUTOMATIC_MODE_CONTROL,
-+ SCL_V_CALC_AUTO_RATIO_EN);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ SCL_AUTOMATIC_MODE_CONTROL,
-+ SCL_H_CALC_AUTO_RATIO_EN);
-+ dal_write_reg(xfm110->base.ctx, addr, value);
-+}
-+
-+static void get_viewport(
-+ struct dce110_transform *xfm110,
-+ struct rect *current_view_port)
-+{
-+ uint32_t value_start;
-+ uint32_t value_size;
-+
-+ if (current_view_port == NULL)
-+ return;
-+
-+ value_start = dal_read_reg(xfm110->base.ctx, SCL_REG(mmVIEWPORT_START));
-+ value_size = dal_read_reg(xfm110->base.ctx, SCL_REG(mmVIEWPORT_SIZE));
-+
-+ current_view_port->x = get_reg_field_value(
-+ value_start,
-+ VIEWPORT_START,
-+ VIEWPORT_X_START);
-+ current_view_port->y = get_reg_field_value(
-+ value_start,
-+ VIEWPORT_START,
-+ VIEWPORT_Y_START);
-+ current_view_port->height = get_reg_field_value(
-+ value_size,
-+ VIEWPORT_SIZE,
-+ VIEWPORT_HEIGHT);
-+ current_view_port->width = get_reg_field_value(
-+ value_size,
-+ VIEWPORT_SIZE,
-+ VIEWPORT_WIDTH);
-+}
-+
-+
-+bool dce110_transform_set_scaler(
-+ struct transform *xfm,
-+ const struct scaler_data *data)
-+{
-+ struct dce110_transform *xfm110 = TO_DCE110_TRANSFORM(xfm);
-+ bool is_scaling_required;
-+ struct dc_context *ctx = xfm->ctx;
-+
-+ {
-+ uint32_t addr = SCL_REG(mmSCL_BYPASS_CONTROL);
-+ uint32_t value = dal_read_reg(xfm->ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ SCL_BYPASS_CONTROL,
-+ SCL_BYPASS_MODE);
-+ dal_write_reg(xfm->ctx, addr, value);
-+ }
-+
-+ disable_enhanced_sharpness(xfm110);
-+
-+ /* 3. Program overscan */
-+ program_overscan(xfm110, &data->overscan);
-+
-+ /* 4. Program taps and configuration */
-+ is_scaling_required = setup_scaling_configuration(xfm110, data);
-+ if (is_scaling_required) {
-+ /* 5. Calculate and program ratio, filter initialization */
-+ struct scl_ratios_inits inits = { 0 };
-+
-+ calculate_inits(xfm110, data, &inits);
-+
-+ program_scl_ratios_inits(xfm110, &inits);
-+
-+ /* 6. Program vertical filters */
-+ if (data->taps.v_taps > 2) {
-+ program_two_taps_filter(xfm110, false, true);
-+
-+ if (!program_multi_taps_filter(xfm110, data, false)) {
-+ dal_logger_write(ctx->logger,
-+ LOG_MAJOR_DCP,
-+ LOG_MINOR_DCP_SCALER,
-+ "Failed vertical taps programming\n");
-+ return false;
-+ }
-+ } else
-+ program_two_taps_filter(xfm110, true, true);
-+
-+ /* 7. Program horizontal filters */
-+ if (data->taps.h_taps > 2) {
-+ program_two_taps_filter(xfm110, false, false);
-+
-+ if (!program_multi_taps_filter(xfm110, data, true)) {
-+ dal_logger_write(ctx->logger,
-+ LOG_MAJOR_DCP,
-+ LOG_MINOR_DCP_SCALER,
-+ "Failed horizontal taps programming\n");
-+ return false;
-+ }
-+ } else
-+ program_two_taps_filter(xfm110, true, false);
-+ }
-+
-+ return true;
-+}
-+
-+void dce110_transform_set_scaler_bypass(struct transform *xfm)
-+{
-+ struct dce110_transform *xfm110 = TO_DCE110_TRANSFORM(xfm);
-+ uint32_t sclv_mode;
-+
-+ disable_enhanced_sharpness(xfm110);
-+
-+ sclv_mode = dal_read_reg(xfm->ctx, SCL_REG(mmSCL_MODE));
-+ set_reg_field_value(sclv_mode, 0, SCL_MODE, SCL_MODE);
-+ set_reg_field_value(sclv_mode, 0, SCL_MODE, SCL_PSCL_EN);
-+ dal_write_reg(xfm->ctx, SCL_REG(mmSCL_MODE), sclv_mode);
-+}
-+
-+bool dce110_transform_update_viewport(
-+ struct transform *xfm,
-+ const struct rect *view_port,
-+ bool is_fbc_attached)
-+{
-+ struct dce110_transform *xfm110 = TO_DCE110_TRANSFORM(xfm);
-+ bool program_req = false;
-+ struct rect current_view_port;
-+
-+ if (view_port == NULL)
-+ return program_req;
-+
-+ get_viewport(xfm110, &current_view_port);
-+
-+ if (current_view_port.x != view_port->x ||
-+ current_view_port.y != view_port->y ||
-+ current_view_port.height != view_port->height ||
-+ current_view_port.width != view_port->width)
-+ program_req = true;
-+
-+ if (program_req) {
-+ /*underlay viewport is programmed with scaler
-+ *program_viewport function pointer is not exposed*/
-+ program_viewport(xfm110, view_port);
-+ }
-+
-+ return program_req;
-+}
-+
-+void dce110_transform_set_scaler_filter(
-+ struct transform *xfm,
-+ struct scaler_filter *filter)
-+{
-+ xfm->filter = filter;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_sclv.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_sclv.c
-new file mode 100644
-index 0000000..bcf20bb
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_transform_sclv.c
-@@ -0,0 +1,531 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "dce110_transform.h"
-+
-+#define NOT_IMPLEMENTED() DAL_LOGGER_NOT_IMPL(LOG_MINOR_COMPONENT_CONTROLLER,\
-+ "TRANSFORM SCALER:%s()\n", __func__)
-+
-+/*
-+*****************************************************************************
-+* Function: calculateViewport
-+*
-+* @brief
-+* Calculates all of the data required to set the viewport
-+*
-+* @param [in] pData: scaler settings data
-+* @param [out] pLumaVp: luma viewport information
-+* @param [out] pChromaVp: chroma viewport information
-+* @param [out] srcResCx2: source chroma resolution times 2 - for multi-taps
-+*
-+*****************************************************************************
-+*/
-+static void calculate_viewport(
-+ const struct scaler_data *scl_data,
-+ struct rect *luma_viewport,
-+ struct rect *chroma_viewport)
-+{
-+ /*Do not set chroma vp for rgb444 pixel format*/
-+ luma_viewport->x = scl_data->viewport.x - scl_data->viewport.x % 2;
-+ luma_viewport->y = scl_data->viewport.y - scl_data->viewport.y % 2;
-+ luma_viewport->width =
-+ scl_data->viewport.width - scl_data->viewport.width % 2;
-+ luma_viewport->height =
-+ scl_data->viewport.height - scl_data->viewport.height % 2;
-+
-+
-+ if (scl_data->dal_pixel_format == PIXEL_FORMAT_422BPP16) {
-+ luma_viewport->width += luma_viewport->width % 2;
-+
-+ chroma_viewport->x = luma_viewport->x / 2;
-+ chroma_viewport->width = luma_viewport->width / 2;
-+ } else if (scl_data->dal_pixel_format == PIXEL_FORMAT_420BPP12) {
-+ luma_viewport->height += luma_viewport->height % 2;
-+ luma_viewport->width += luma_viewport->width % 2;
-+ /*for 420 video chroma is 1/4 the area of luma, scaled
-+ *vertically and horizontally
-+ */
-+ chroma_viewport->x = luma_viewport->x / 2;
-+ chroma_viewport->y = luma_viewport->y / 2;
-+ chroma_viewport->height = luma_viewport->height / 2;
-+ chroma_viewport->width = luma_viewport->width / 2;
-+ }
-+}
-+
-+
-+static void program_viewport(
-+ struct dce110_transform *xfm110,
-+ struct rect *luma_view_port,
-+ struct rect *chroma_view_port)
-+{
-+ struct dc_context *ctx = xfm110->base.ctx;
-+ uint32_t value = 0;
-+ uint32_t addr = 0;
-+
-+ if (luma_view_port->width != 0 && luma_view_port->height != 0) {
-+ addr = mmSCLV_VIEWPORT_START;
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ luma_view_port->x,
-+ SCLV_VIEWPORT_START,
-+ VIEWPORT_X_START);
-+ set_reg_field_value(
-+ value,
-+ luma_view_port->y,
-+ SCLV_VIEWPORT_START,
-+ VIEWPORT_Y_START);
-+ dal_write_reg(ctx, addr, value);
-+
-+ addr = mmSCLV_VIEWPORT_SIZE;
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ luma_view_port->height,
-+ SCLV_VIEWPORT_SIZE,
-+ VIEWPORT_HEIGHT);
-+ set_reg_field_value(
-+ value,
-+ luma_view_port->width,
-+ SCLV_VIEWPORT_SIZE,
-+ VIEWPORT_WIDTH);
-+ dal_write_reg(ctx, addr, value);
-+ }
-+
-+ if (chroma_view_port->width != 0 && chroma_view_port->height != 0) {
-+ addr = mmSCLV_VIEWPORT_START_C;
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ chroma_view_port->x,
-+ SCLV_VIEWPORT_START_C,
-+ VIEWPORT_X_START_C);
-+ set_reg_field_value(
-+ value,
-+ chroma_view_port->y,
-+ SCLV_VIEWPORT_START_C,
-+ VIEWPORT_Y_START_C);
-+ dal_write_reg(ctx, addr, value);
-+
-+ addr = mmSCLV_VIEWPORT_SIZE_C;
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ chroma_view_port->height,
-+ SCLV_VIEWPORT_SIZE_C,
-+ VIEWPORT_HEIGHT_C);
-+ set_reg_field_value(
-+ value,
-+ chroma_view_port->width,
-+ SCLV_VIEWPORT_SIZE_C,
-+ VIEWPORT_WIDTH_C);
-+ dal_write_reg(ctx, addr, value);
-+ }
-+ /* TODO: add stereo support */
-+}
-+
-+
-+/* Until and For MPO video play story, to reduce time for implementation,
-+ * below limits are applied for now: 2_TAPS only
-+ * Use auto-calculated filter values
-+ * Following routines will be empty for now:
-+ *
-+ * programSclRatiosInits -- calcualate scaler ratio manually
-+ * calculateInits --- calcualate scaler ratio manually
-+ * programFilter -- multi-taps
-+ * GetOptimalNumberOfTaps -- will hard coded to 2 TAPS
-+ * GetNextLowerNumberOfTaps -- will hard coded to 2TAPS
-+ * validateRequestedScaleRatio - used by GetOptimalNumberOfTaps internally
-+ */
-+
-+/**
-+* Function:
-+* void setup_scaling_configuration
-+*
-+* Purpose: setup scaling mode : bypass, RGb, YCbCr and nummber of taps
-+* Input: data
-+*
-+* Output:
-+ void
-+*/
-+static bool setup_scaling_configuration(
-+ struct dce110_transform *xfm110,
-+ const struct scaler_data *data)
-+{
-+ bool is_scaling_needed = false;
-+ struct dc_context *ctx = xfm110->base.ctx;
-+ uint32_t value = 0;
-+
-+ if (data->taps.h_taps + data->taps.v_taps > 2) {
-+ set_reg_field_value(value, 1, SCLV_MODE, SCL_MODE);
-+ set_reg_field_value(value, 1, SCLV_MODE, SCL_PSCL_EN);
-+ is_scaling_needed = true;
-+ } else {
-+ set_reg_field_value(value, 0, SCLV_MODE, SCL_MODE);
-+ set_reg_field_value(value, 0, SCLV_MODE, SCL_PSCL_EN);
-+ }
-+
-+ if (data->taps.h_taps_c + data->taps.v_taps_c > 2) {
-+ set_reg_field_value(value, 1, SCLV_MODE, SCL_MODE_C);
-+ set_reg_field_value(value, 1, SCLV_MODE, SCL_PSCL_EN_C);
-+ is_scaling_needed = true;
-+ } else if (data->dal_pixel_format != PIXEL_FORMAT_420BPP12 &&
-+ data->dal_pixel_format != PIXEL_FORMAT_422BPP16) {
-+ set_reg_field_value(
-+ value,
-+ get_reg_field_value(value, SCLV_MODE, SCL_MODE),
-+ SCLV_MODE,
-+ SCL_MODE_C);
-+ set_reg_field_value(
-+ value,
-+ get_reg_field_value(value, SCLV_MODE, SCL_PSCL_EN),
-+ SCLV_MODE,
-+ SCL_PSCL_EN_C);
-+ } else {
-+ set_reg_field_value(value, 0, SCLV_MODE, SCL_MODE_C);
-+ set_reg_field_value(value, 0, SCLV_MODE, SCL_PSCL_EN_C);
-+ }
-+ dal_write_reg(ctx, mmSCLV_MODE, value);
-+
-+ {
-+ value = dal_read_reg(ctx, mmSCLV_TAP_CONTROL);
-+
-+ set_reg_field_value(value, data->taps.h_taps - 1,
-+ SCLV_TAP_CONTROL, SCL_H_NUM_OF_TAPS);
-+
-+ set_reg_field_value(value, data->taps.v_taps - 1,
-+ SCLV_TAP_CONTROL, SCL_V_NUM_OF_TAPS);
-+
-+ set_reg_field_value(value, data->taps.h_taps_c - 1,
-+ SCLV_TAP_CONTROL, SCL_H_NUM_OF_TAPS_C);
-+
-+ set_reg_field_value(value, data->taps.v_taps_c - 1,
-+ SCLV_TAP_CONTROL, SCL_V_NUM_OF_TAPS_C);
-+
-+ dal_write_reg(ctx, mmSCLV_TAP_CONTROL, value);
-+ }
-+
-+ {
-+ /* we can ignore this register because we are ok with hw
-+ * default 0 -- change to 1 according to dal2 code*/
-+ value = dal_read_reg(ctx, mmSCLV_CONTROL);
-+ /* 0 - Replaced out of bound pixels with black pixel
-+ * (or any other required color) */
-+ set_reg_field_value(value, 1, SCLV_CONTROL, SCL_BOUNDARY_MODE);
-+
-+ /* 1 - Replaced out of bound pixels with the edge pixel. */
-+ dal_write_reg(ctx, mmSCLV_CONTROL, value);
-+ }
-+
-+ return is_scaling_needed;
-+}
-+
-+/**
-+* Function:
-+* void program_overscan
-+*
-+* Purpose: Programs overscan border
-+* Input: overscan
-+*
-+* Output:
-+ void
-+*/
-+static void program_overscan(
-+ struct dce110_transform *xfm110,
-+ const struct overscan_info *overscan)
-+{
-+ uint32_t overscan_left_right = 0;
-+ uint32_t overscan_top_bottom = 0;
-+
-+ set_reg_field_value(overscan_left_right, overscan->left,
-+ SCLV_EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_LEFT);
-+
-+ set_reg_field_value(overscan_left_right, overscan->right,
-+ SCLV_EXT_OVERSCAN_LEFT_RIGHT, EXT_OVERSCAN_RIGHT);
-+
-+ set_reg_field_value(overscan_top_bottom, overscan->top,
-+ SCLV_EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_TOP);
-+
-+ set_reg_field_value(overscan_top_bottom, overscan->bottom,
-+ SCLV_EXT_OVERSCAN_TOP_BOTTOM, EXT_OVERSCAN_BOTTOM);
-+
-+ dal_write_reg(xfm110->base.ctx,
-+ mmSCLV_EXT_OVERSCAN_LEFT_RIGHT,
-+ overscan_left_right);
-+
-+ dal_write_reg(xfm110->base.ctx,
-+ mmSCLV_EXT_OVERSCAN_TOP_BOTTOM,
-+ overscan_top_bottom);
-+}
-+/*
-+static void setup_auto_scaling(struct dce110_transform *xfm110)
-+{
-+ uint32_t value = 0;
-+ set_reg_field_value(value, 1, SCLV_AUTOMATIC_MODE_CONTROL,
-+ SCL_V_CALC_AUTO_RATIO_EN);
-+ set_reg_field_value(value, 1, SCLV_AUTOMATIC_MODE_CONTROL,
-+ SCL_H_CALC_AUTO_RATIO_EN);
-+ dal_write_reg(xfm->ctx,
-+ xfm->regs[IDX_SCL_AUTOMATIC_MODE_CONTROL],
-+ value);
-+}
-+*/
-+
-+static void program_two_taps_filter_horz(
-+ struct dce110_transform *xfm110,
-+ bool hardcode_coff)
-+{
-+ uint32_t value = 0;
-+
-+ if (hardcode_coff)
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ SCLV_HORZ_FILTER_CONTROL,
-+ SCL_H_2TAP_HARDCODE_COEF_EN);
-+
-+ dal_write_reg(xfm110->base.ctx,
-+ mmSCLV_HORZ_FILTER_CONTROL,
-+ value);
-+}
-+
-+static void program_two_taps_filter_vert(
-+ struct dce110_transform *xfm110,
-+ bool hardcode_coff)
-+{
-+ uint32_t value = 0;
-+
-+ if (hardcode_coff)
-+ set_reg_field_value(value, 1, SCLV_VERT_FILTER_CONTROL,
-+ SCL_V_2TAP_HARDCODE_COEF_EN);
-+
-+ dal_write_reg(xfm110->base.ctx,
-+ mmSCLV_VERT_FILTER_CONTROL,
-+ value);
-+}
-+
-+static void set_coeff_update_complete(
-+ struct dce110_transform *xfm110)
-+{
-+ /*TODO: Until now, only scaler bypass, up-scaler 2 -TAPS coeff auto
-+ * calculation are implemented. Coefficient RAM is not used
-+ * Do not check this flag yet
-+ */
-+
-+ /*uint32_t value;
-+ uint32_t addr = xfm->regs[IDX_SCL_UPDATE];
-+
-+ value = dal_read_reg(xfm->ctx, addr);
-+ set_reg_field_value(value, 0,
-+ SCL_UPDATE, SCL_COEF_UPDATE_COMPLETE);
-+ dal_write_reg(xfm->ctx, addr, value);*/
-+}
-+
-+static bool program_multi_taps_filter(
-+ struct dce110_transform *xfm110,
-+ const struct scaler_data *data,
-+ bool horizontal)
-+{
-+ struct dc_context *ctx = xfm110->base.ctx;
-+
-+ NOT_IMPLEMENTED();
-+ return false;
-+}
-+
-+static void calculate_inits(
-+ struct dce110_transform *xfm110,
-+ const struct scaler_data *data,
-+ struct sclv_ratios_inits *inits,
-+ struct rect *luma_viewport,
-+ struct rect *chroma_viewport)
-+{
-+ if (data->dal_pixel_format == PIXEL_FORMAT_420BPP12 ||
-+ data->dal_pixel_format == PIXEL_FORMAT_422BPP16)
-+ inits->chroma_enable = true;
-+
-+ /* TODO: implement rest of this function properly */
-+ if (inits->chroma_enable) {
-+ inits->h_int_scale_ratio_luma = 0x1000000;
-+ inits->v_int_scale_ratio_luma = 0x1000000;
-+ inits->h_int_scale_ratio_chroma = 0x800000;
-+ inits->v_int_scale_ratio_chroma = 0x800000;
-+ }
-+}
-+
-+static void program_scl_ratios_inits(
-+ struct dce110_transform *xfm110,
-+ struct sclv_ratios_inits *inits)
-+{
-+ struct dc_context *ctx = xfm110->base.ctx;
-+ uint32_t addr = mmSCLV_HORZ_FILTER_SCALE_RATIO;
-+ uint32_t value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ inits->h_int_scale_ratio_luma,
-+ SCLV_HORZ_FILTER_SCALE_RATIO,
-+ SCL_H_SCALE_RATIO);
-+ dal_write_reg(ctx, addr, value);
-+
-+ addr = mmSCLV_VERT_FILTER_SCALE_RATIO;
-+ value = dal_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ inits->v_int_scale_ratio_luma,
-+ SCLV_VERT_FILTER_SCALE_RATIO,
-+ SCL_V_SCALE_RATIO);
-+ dal_write_reg(ctx, addr, value);
-+
-+ addr = mmSCLV_HORZ_FILTER_SCALE_RATIO_C;
-+ value = dal_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ inits->h_int_scale_ratio_chroma,
-+ SCLV_HORZ_FILTER_SCALE_RATIO_C,
-+ SCL_H_SCALE_RATIO_C);
-+ dal_write_reg(ctx, addr, value);
-+
-+ addr = mmSCLV_VERT_FILTER_SCALE_RATIO_C;
-+ value = dal_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ inits->v_int_scale_ratio_chroma,
-+ SCLV_VERT_FILTER_SCALE_RATIO_C,
-+ SCL_V_SCALE_RATIO_C);
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+void dce110_transform_underlay_set_scalerv_bypass(struct transform *xfm)
-+{
-+ uint32_t addr = mmSCLV_MODE;
-+ uint32_t value = dal_read_reg(xfm->ctx, addr);
-+
-+ set_reg_field_value(value, 0, SCLV_MODE, SCL_MODE);
-+ set_reg_field_value(value, 0, SCLV_MODE, SCL_MODE_C);
-+ set_reg_field_value(value, 0, SCLV_MODE, SCL_PSCL_EN);
-+ set_reg_field_value(value, 0, SCLV_MODE, SCL_PSCL_EN_C);
-+ dal_write_reg(xfm->ctx, addr, value);
-+}
-+
-+bool dce110_transform_underlay_is_scaling_enabled(struct transform *xfm)
-+{
-+ uint32_t value = dal_read_reg(xfm->ctx, mmSCLV_MODE);
-+ uint8_t scl_mode = get_reg_field_value(value, SCLV_MODE, SCL_MODE);
-+
-+ return scl_mode == 0;
-+}
-+
-+/* TODO: sync this one with DAL2 */
-+bool dce110_transform_underlay_set_scaler(
-+ struct transform *xfm,
-+ const struct scaler_data *data)
-+{
-+ struct dce110_transform *xfm110 = TO_DCE110_TRANSFORM(xfm);
-+ bool is_scaling_required;
-+ struct rect luma_viewport = {0};
-+ struct rect chroma_viewport = {0};
-+ struct dc_context *ctx = xfm->ctx;
-+
-+ /* 1. Lock Scaler TODO: enable?*/
-+ /*set_scaler_update_lock(xfm, true);*/
-+
-+ /* 2. Calculate viewport, viewport programming should happen after init
-+ * calculations as they may require an adjustment in the viewport.
-+ */
-+
-+ calculate_viewport(data, &luma_viewport, &chroma_viewport);
-+
-+ /* 3. Program overscan */
-+ program_overscan(xfm110, &data->overscan);
-+
-+ /* 4. Program taps and configuration */
-+ is_scaling_required = setup_scaling_configuration(xfm110, data);
-+
-+ if (is_scaling_required) {
-+ /* 5. Calculate and program ratio, filter initialization */
-+
-+ struct sclv_ratios_inits inits = { 0 };
-+
-+ calculate_inits(
-+ xfm110,
-+ data,
-+ &inits,
-+ &luma_viewport,
-+ &chroma_viewport);
-+
-+ program_scl_ratios_inits(xfm110, &inits);
-+
-+ /*scaler coeff of 2-TAPS use hardware auto calculated value*/
-+
-+ /* 6. Program vertical filters */
-+ if (data->taps.v_taps > 2) {
-+ program_two_taps_filter_vert(xfm110, false);
-+
-+ if (!program_multi_taps_filter(xfm110, data, false)) {
-+ dal_logger_write(ctx->logger,
-+ LOG_MAJOR_DCP,
-+ LOG_MINOR_DCP_SCALER,
-+ "Failed vertical taps programming\n");
-+ return false;
-+ }
-+ } else
-+ program_two_taps_filter_vert(xfm110, true);
-+
-+ /* 7. Program horizontal filters */
-+ if (data->taps.h_taps > 2) {
-+ program_two_taps_filter_horz(xfm110, false);
-+
-+ if (!program_multi_taps_filter(xfm110, data, true)) {
-+ dal_logger_write(ctx->logger,
-+ LOG_MAJOR_DCP,
-+ LOG_MINOR_DCP_SCALER,
-+ "Failed horizontal taps programming\n");
-+ return false;
-+ }
-+ } else
-+ program_two_taps_filter_horz(xfm110, true);
-+ }
-+
-+ /* 8. Program the viewport */
-+ if (data->flags.bits.SHOULD_PROGRAM_VIEWPORT)
-+ program_viewport(xfm110, &luma_viewport, &chroma_viewport);
-+
-+ /* 9. Unlock the Scaler TODO: enable?*/
-+ /* Every call to "set_scaler_update_lock(xfm, TRUE)"
-+ * must have a corresponding call to
-+ * "set_scaler_update_lock(xfm, FALSE)" */
-+ /*set_scaler_update_lock(xfm, false);*/
-+
-+ /* TODO: investigate purpose/need of SHOULD_UNLOCK */
-+ if (data->flags.bits.SHOULD_UNLOCK == false)
-+ set_coeff_update_complete(xfm110);
-+
-+ return true;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dcs/Makefile b/drivers/gpu/drm/amd/dal/dc/dcs/Makefile
-new file mode 100644
-index 0000000..a266942
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dcs/Makefile
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the 'gpu' sub-component of DAL.
-+# It provides the control and status of HW adapter resources,
-+# that are global for the ASIC and sharable between pipes.
-+
-+DCS = ddc_service.o ddc_i2caux_helper.o
-+
-+AMD_DAL_DCS = $(addprefix $(AMDDALPATH)/dc/dcs/,$(DCS))
-+
-+AMD_DAL_FILES += $(AMD_DAL_DCS)
-diff --git a/drivers/gpu/drm/amd/dal/dc/dcs/ddc_i2caux_helper.c b/drivers/gpu/drm/amd/dal/dc/dcs/ddc_i2caux_helper.c
-new file mode 100644
-index 0000000..a4442d6
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dcs/ddc_i2caux_helper.c
-@@ -0,0 +1,159 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "ddc_i2caux_helper.h"
-+#include "include/ddc_service_types.h"
-+#include "include/vector.h"
-+
-+struct i2c_payloads {
-+ struct vector payloads;
-+};
-+
-+struct aux_payloads {
-+ struct vector payloads;
-+};
-+
-+struct i2c_payloads *dal_ddc_i2c_payloads_create(struct dc_context *ctx, uint32_t count)
-+{
-+ struct i2c_payloads *payloads;
-+
-+ payloads = dc_service_alloc(ctx, sizeof(struct i2c_payloads));
-+
-+ if (!payloads)
-+ return NULL;
-+
-+ if (dal_vector_construct(
-+ &payloads->payloads, ctx, count, sizeof(struct i2c_payload)))
-+ return payloads;
-+
-+ dc_service_free(ctx, payloads);
-+ return NULL;
-+
-+}
-+
-+struct i2c_payload *dal_ddc_i2c_payloads_get(struct i2c_payloads *p)
-+{
-+ return (struct i2c_payload *)p->payloads.container;
-+}
-+
-+uint32_t dal_ddc_i2c_payloads_get_count(struct i2c_payloads *p)
-+{
-+ return p->payloads.count;
-+}
-+
-+void dal_ddc_i2c_payloads_destroy(struct i2c_payloads **p)
-+{
-+ if (!p || !*p)
-+ return;
-+ dal_vector_destruct(&(*p)->payloads);
-+ dc_service_free((*p)->payloads.ctx, *p);
-+ *p = NULL;
-+
-+}
-+
-+struct aux_payloads *dal_ddc_aux_payloads_create(struct dc_context *ctx, uint32_t count)
-+{
-+ struct aux_payloads *payloads;
-+
-+ payloads = dc_service_alloc(ctx, sizeof(struct aux_payloads));
-+
-+ if (!payloads)
-+ return NULL;
-+
-+ if (dal_vector_construct(
-+ &payloads->payloads, ctx, count, sizeof(struct aux_payloads)))
-+ return payloads;
-+
-+ dc_service_free(ctx, payloads);
-+ return NULL;
-+}
-+
-+struct aux_payload *dal_ddc_aux_payloads_get(struct aux_payloads *p)
-+{
-+ return (struct aux_payload *)p->payloads.container;
-+}
-+
-+uint32_t dal_ddc_aux_payloads_get_count(struct aux_payloads *p)
-+{
-+ return p->payloads.count;
-+}
-+
-+
-+void dal_ddc_aux_payloads_destroy(struct aux_payloads **p)
-+{
-+ if (!p || !*p)
-+ return;
-+
-+ dal_vector_destruct(&(*p)->payloads);
-+ dc_service_free((*p)->payloads.ctx, *p);
-+ *p = NULL;
-+}
-+
-+#define DDC_MIN(a, b) (((a) < (b)) ? (a) : (b))
-+
-+void dal_ddc_i2c_payloads_add(
-+ struct i2c_payloads *payloads,
-+ uint32_t address,
-+ uint32_t len,
-+ uint8_t *data,
-+ bool write)
-+{
-+ uint32_t payload_size = EDID_SEGMENT_SIZE;
-+ uint32_t pos;
-+
-+ for (pos = 0; pos < len; pos += payload_size) {
-+ struct i2c_payload payload = {
-+ .write = write,
-+ .address = address,
-+ .length = DDC_MIN(payload_size, len - pos),
-+ .data = data + pos };
-+ dal_vector_append(&payloads->payloads, &payload);
-+ }
-+
-+}
-+
-+void dal_ddc_aux_payloads_add(
-+ struct aux_payloads *payloads,
-+ uint32_t address,
-+ uint32_t len,
-+ uint8_t *data,
-+ bool write)
-+{
-+ uint32_t payload_size = DEFAULT_AUX_MAX_DATA_SIZE;
-+ uint32_t pos;
-+
-+ for (pos = 0; pos < len; pos += payload_size) {
-+ struct aux_payload payload = {
-+ .i2c_over_aux = true,
-+ .write = write,
-+ .address = address,
-+ .length = DDC_MIN(payload_size, len - pos),
-+ .data = data + pos };
-+ dal_vector_append(&payloads->payloads, &payload);
-+ }
-+}
-+
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dcs/ddc_i2caux_helper.h b/drivers/gpu/drm/amd/dal/dc/dcs/ddc_i2caux_helper.h
-new file mode 100644
-index 0000000..bb628cd
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dcs/ddc_i2caux_helper.h
-@@ -0,0 +1,60 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_I2CAUX_HELPER_H__
-+#define __DAL_I2CAUX_HELPER_H__
-+
-+#include "include/i2caux_interface.h"
-+
-+#define EDID_SEGMENT_SIZE 256
-+
-+struct i2c_payloads;
-+struct aux_payloads;
-+
-+struct i2c_payloads *dal_ddc_i2c_payloads_create(struct dc_context *ctx, uint32_t count);
-+struct i2c_payload *dal_ddc_i2c_payloads_get(struct i2c_payloads *p);
-+uint32_t dal_ddc_i2c_payloads_get_count(struct i2c_payloads *p);
-+void dal_ddc_i2c_payloads_destroy(struct i2c_payloads **p);
-+
-+struct aux_payloads *dal_ddc_aux_payloads_create(struct dc_context *ctx, uint32_t count);
-+struct aux_payload *dal_ddc_aux_payloads_get(struct aux_payloads *p);
-+uint32_t dal_ddc_aux_payloads_get_count(struct aux_payloads *p);
-+void dal_ddc_aux_payloads_destroy(struct aux_payloads **p);
-+
-+void dal_ddc_i2c_payloads_add(
-+ struct i2c_payloads *payloads,
-+ uint32_t address,
-+ uint32_t len,
-+ uint8_t *data,
-+ bool write);
-+
-+void dal_ddc_aux_payloads_add(
-+ struct aux_payloads *payloads,
-+ uint32_t address,
-+ uint32_t len,
-+ uint8_t *data,
-+ bool write);
-+
-+#endif /* __DAL_I2CAUX_HELPER_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dcs/ddc_service.c b/drivers/gpu/drm/amd/dal/dc/dcs/ddc_service.c
-new file mode 100644
-index 0000000..5436704
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dcs/ddc_service.c
-@@ -0,0 +1,1034 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/adapter_service_interface.h"
-+#include "include/i2caux_interface.h"
-+#include "include/ddc_service_interface.h"
-+#include "include/ddc_service_types.h"
-+#include "include/grph_object_id.h"
-+#include "include/dpcd_defs.h"
-+#include "include/logger_interface.h"
-+#include "ddc_i2caux_helper.h"
-+#include "ddc_service.h"
-+#include "dal_services_types.h"
-+
-+#define AUX_POWER_UP_WA_DELAY 500
-+#define I2C_OVER_AUX_DEFER_WA_DELAY 70
-+
-+/* CV smart dongle slave address for retrieving supported HDTV modes*/
-+#define CV_SMART_DONGLE_ADDRESS 0x20
-+/* DVI-HDMI dongle slave address for retrieving dongle signature*/
-+#define DVI_HDMI_DONGLE_ADDRESS 0x68
-+static const int8_t dvi_hdmi_dongle_signature_str[] = "6140063500G";
-+struct dvi_hdmi_dongle_signature_data {
-+ int8_t vendor[3];/* "AMD" */
-+ uint8_t version[2];
-+ uint8_t size;
-+ int8_t id[11];/* "6140063500G"*/
-+};
-+/* DP-HDMI dongle slave address for retrieving dongle signature*/
-+#define DP_HDMI_DONGLE_ADDRESS 0x40
-+static const uint8_t dp_hdmi_dongle_signature_str[] = "DP-HDMI ADAPTOR";
-+#define DP_HDMI_DONGLE_SIGNATURE_EOT 0x04
-+
-+struct dp_hdmi_dongle_signature_data {
-+ int8_t id[15];/* "DP-HDMI ADAPTOR"*/
-+ uint8_t eot;/* end of transmition '\x4' */
-+};
-+
-+/* Address range from 0x00 to 0x1F.*/
-+#define DP_ADAPTOR_TYPE2_SIZE 0x20
-+#define DP_ADAPTOR_TYPE2_REG_ID 0x10
-+#define DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK 0x1D
-+/* Identifies adaptor as Dual-mode adaptor */
-+#define DP_ADAPTOR_TYPE2_ID 0xA0
-+/* MHz*/
-+#define DP_ADAPTOR_TYPE2_MAX_TMDS_CLK 600
-+/* MHz*/
-+#define DP_ADAPTOR_TYPE2_MIN_TMDS_CLK 25
-+/* kHZ*/
-+#define DP_ADAPTOR_DVI_MAX_TMDS_CLK 165000
-+/* kHZ*/
-+#define DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK 165000
-+
-+#define DDC_I2C_COMMAND_ENGINE I2C_COMMAND_ENGINE_SW
-+
-+enum edid_read_result {
-+ EDID_READ_RESULT_EDID_MATCH = 0,
-+ EDID_READ_RESULT_EDID_MISMATCH,
-+ EDID_READ_RESULT_CHECKSUM_READ_ERR,
-+ EDID_READ_RESULT_VENDOR_READ_ERR
-+};
-+
-+/* SCDC Address defines (HDMI 2.0)*/
-+#define HDMI_SCDC_WRITE_UPDATE_0_ARRAY 3
-+#define HDMI_SCDC_ADDRESS 0x54
-+#define HDMI_SCDC_SINK_VERSION 0x01
-+#define HDMI_SCDC_SOURCE_VERSION 0x02
-+#define HDMI_SCDC_UPDATE_0 0x10
-+#define HDMI_SCDC_TMDS_CONFIG 0x20
-+#define HDMI_SCDC_SCRAMBLER_STATUS 0x21
-+#define HDMI_SCDC_CONFIG_0 0x30
-+#define HDMI_SCDC_STATUS_FLAGS 0x40
-+#define HDMI_SCDC_ERR_DETECT 0x50
-+#define HDMI_SCDC_TEST_CONFIG 0xC0
-+
-+
-+union hdmi_scdc_update_read_data
-+{
-+ uint8_t byte[2];
-+ struct
-+ {
-+ uint8_t STATUS_UPDATE:1;
-+ uint8_t CED_UPDATE:1;
-+ uint8_t RR_TEST:1;
-+ uint8_t RESERVED:5;
-+ uint8_t RESERVED2:8;
-+ } fields;
-+};
-+
-+union hdmi_scdc_status_flags_data
-+{
-+ uint8_t byte[2];
-+ struct
-+ {
-+ uint8_t CLOCK_DETECTED:1;
-+ uint8_t CH0_LOCKED:1;
-+ uint8_t CH1_LOCKED:1;
-+ uint8_t CH2_LOCKED:1;
-+ uint8_t RESERVED:4;
-+ uint8_t RESERVED2:8;
-+ } fields;
-+};
-+
-+union hdmi_scdc_ced_data
-+{
-+ uint8_t byte[7];
-+ struct
-+ {
-+ uint8_t CH0_8LOW:8;
-+ uint8_t CH0_7HIGH:7;
-+ uint8_t CH0_VALID:1;
-+ uint8_t CH1_8LOW:8;
-+ uint8_t CH1_7HIGH:7;
-+ uint8_t CH1_VALID:1;
-+ uint8_t CH2_8LOW:8;
-+ uint8_t CH2_7HIGH:7;
-+ uint8_t CH2_VALID:1;
-+ uint8_t CHECKSUM:8;
-+ } fields;
-+};
-+
-+union hdmi_scdc_test_config_Data
-+{
-+ uint8_t byte;
-+ struct
-+ {
-+ uint8_t TEST_READ_REQUEST_DELAY:7;
-+ uint8_t TEST_READ_REQUEST: 1;
-+ } fields;
-+};
-+
-+
-+
-+union ddc_wa {
-+ struct {
-+ uint32_t DP_SKIP_POWER_OFF:1;
-+ uint32_t DP_AUX_POWER_UP_WA_DELAY:1;
-+ } bits;
-+ uint32_t raw;
-+};
-+
-+struct ddc_flags {
-+ uint8_t EDID_QUERY_DONE_ONCE:1;
-+ uint8_t IS_INTERNAL_DISPLAY:1;
-+ uint8_t FORCE_READ_REPEATED_START:1;
-+ uint8_t EDID_STRESS_READ:1;
-+
-+};
-+
-+struct ddc_service {
-+ struct ddc *ddc_pin;
-+ struct ddc_flags flags;
-+ union ddc_wa wa;
-+ enum ddc_transaction_type transaction_type;
-+ enum display_dongle_type dongle_type;
-+ struct dp_receiver_id_info dp_receiver_id_info;
-+ struct adapter_service *as;
-+ struct dc_context *ctx;
-+
-+ uint32_t address;
-+ uint32_t edid_buf_len;
-+ uint8_t edid_buf[MAX_EDID_BUFFER_SIZE];
-+};
-+
-+static bool construct(
-+ struct ddc_service *ddc_service,
-+ struct ddc_service_init_data *init_data)
-+{
-+ enum connector_id connector_id =
-+ dal_graphics_object_id_get_connector_id(init_data->id);
-+
-+ ddc_service->ctx = init_data->ctx;
-+ ddc_service->as = init_data->as;
-+ ddc_service->ddc_pin = dal_adapter_service_obtain_ddc(
-+ init_data->as, init_data->id);
-+
-+ ddc_service->flags.EDID_QUERY_DONE_ONCE = false;
-+
-+ ddc_service->flags.FORCE_READ_REPEATED_START =
-+ dal_adapter_service_is_feature_supported(
-+ FEATURE_DDC_READ_FORCE_REPEATED_START);
-+
-+ ddc_service->flags.EDID_STRESS_READ =
-+ dal_adapter_service_is_feature_supported(
-+ FEATURE_EDID_STRESS_READ);
-+
-+
-+ ddc_service->flags.IS_INTERNAL_DISPLAY =
-+ connector_id == CONNECTOR_ID_EDP ||
-+ connector_id == CONNECTOR_ID_LVDS;
-+
-+ ddc_service->wa.raw = 0;
-+ return true;
-+}
-+
-+struct ddc_service *dal_ddc_service_create(
-+ struct ddc_service_init_data *init_data)
-+{
-+ struct ddc_service *ddc_service;
-+
-+ ddc_service = dc_service_alloc(init_data->ctx, sizeof(struct ddc_service));
-+
-+ if (!ddc_service)
-+ return NULL;
-+
-+ if (construct(ddc_service, init_data))
-+ return ddc_service;
-+
-+ dc_service_free(init_data->ctx, ddc_service);
-+ return NULL;
-+}
-+
-+static void destruct(struct ddc_service *ddc)
-+{
-+ if (ddc->ddc_pin)
-+ dal_adapter_service_release_ddc(ddc->as, ddc->ddc_pin);
-+}
-+
-+void dal_ddc_service_destroy(struct ddc_service **ddc)
-+{
-+ if (!ddc || !*ddc) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+ destruct(*ddc);
-+ dc_service_free((*ddc)->ctx, *ddc);
-+ *ddc = NULL;
-+}
-+
-+enum ddc_service_type dal_ddc_service_get_type(struct ddc_service *ddc)
-+{
-+ return DDC_SERVICE_TYPE_CONNECTOR;
-+}
-+
-+void dal_ddc_service_set_transaction_type(
-+ struct ddc_service *ddc,
-+ enum ddc_transaction_type type)
-+{
-+ ddc->transaction_type = type;
-+}
-+
-+bool dal_ddc_service_is_in_aux_transaction_mode(struct ddc_service *ddc)
-+{
-+ switch (ddc->transaction_type) {
-+ case DDC_TRANSACTION_TYPE_I2C_OVER_AUX:
-+ case DDC_TRANSACTION_TYPE_I2C_OVER_AUX_WITH_DEFER:
-+ case DDC_TRANSACTION_TYPE_I2C_OVER_AUX_RETRY_DEFER:
-+ return true;
-+ default:
-+ break;
-+ }
-+ return false;
-+}
-+
-+void ddc_service_set_dongle_type(struct ddc_service *ddc,
-+ enum display_dongle_type dongle_type)
-+{
-+ ddc->dongle_type = dongle_type;
-+}
-+
-+static uint32_t defer_delay_converter_wa(
-+ struct ddc_service *ddc,
-+ uint32_t defer_delay)
-+{
-+ struct dp_receiver_id_info dp_rec_info = {0};
-+
-+ if (dal_ddc_service_get_dp_receiver_id_info(ddc, &dp_rec_info) &&
-+ (dp_rec_info.branch_id == DP_BRANCH_DEVICE_ID_4) &&
-+ !dal_strncmp(dp_rec_info.branch_name,
-+ DP_DVI_CONVERTER_ID_4,
-+ sizeof(dp_rec_info.branch_name)))
-+ return defer_delay > I2C_OVER_AUX_DEFER_WA_DELAY ?
-+ defer_delay : I2C_OVER_AUX_DEFER_WA_DELAY;
-+
-+ return defer_delay;
-+
-+}
-+
-+#define DP_TRANSLATOR_DELAY 5
-+
-+static uint32_t get_defer_delay(struct ddc_service *ddc)
-+{
-+ uint32_t defer_delay = 0;
-+
-+ switch (ddc->transaction_type) {
-+ case DDC_TRANSACTION_TYPE_I2C_OVER_AUX:
-+ if ((DISPLAY_DONGLE_DP_VGA_CONVERTER == ddc->dongle_type) ||
-+ (DISPLAY_DONGLE_DP_DVI_CONVERTER == ddc->dongle_type) ||
-+ (DISPLAY_DONGLE_DP_HDMI_CONVERTER ==
-+ ddc->dongle_type)) {
-+
-+ defer_delay = DP_TRANSLATOR_DELAY;
-+
-+ defer_delay =
-+ defer_delay_converter_wa(ddc, defer_delay);
-+
-+ } else /*sink has a delay different from an Active Converter*/
-+ defer_delay = 0;
-+ break;
-+ case DDC_TRANSACTION_TYPE_I2C_OVER_AUX_WITH_DEFER:
-+ defer_delay = DP_TRANSLATOR_DELAY;
-+ break;
-+ default:
-+ break;
-+ }
-+ return defer_delay;
-+}
-+
-+static bool i2c_read(
-+ struct ddc_service *ddc,
-+ uint32_t address,
-+ uint8_t *buffer,
-+ uint32_t len)
-+{
-+ uint8_t offs_data = 0;
-+ struct i2c_payload payloads[2] = {
-+ {
-+ .write = true,
-+ .address = address,
-+ .length = 1,
-+ .data = &offs_data },
-+ {
-+ .write = false,
-+ .address = address,
-+ .length = len,
-+ .data = buffer } };
-+
-+ struct i2c_command command = {
-+ .payloads = payloads,
-+ .number_of_payloads = 2,
-+ .engine = DDC_I2C_COMMAND_ENGINE,
-+ .speed = dal_adapter_service_get_sw_i2c_speed(ddc->as) };
-+
-+ return dal_i2caux_submit_i2c_command(
-+ dal_adapter_service_get_i2caux(ddc->as),
-+ ddc->ddc_pin,
-+ &command);
-+}
-+
-+static uint8_t aux_read_edid_block(
-+ struct ddc_service *ddc,
-+ uint8_t address,
-+ uint8_t index,
-+ uint8_t *buf)
-+{
-+ struct aux_command cmd = {
-+ .payloads = NULL,
-+ .number_of_payloads = 0,
-+ .defer_delay = get_defer_delay(ddc),
-+ .max_defer_write_retry = 0 };
-+
-+ uint8_t retrieved = 0;
-+ uint8_t base_offset =
-+ (index % DDC_EDID_BLOCKS_PER_SEGMENT) * DDC_EDID_BLOCK_SIZE;
-+ uint8_t segment = index / DDC_EDID_BLOCKS_PER_SEGMENT;
-+
-+ for (retrieved = 0; retrieved < DDC_EDID_BLOCK_SIZE;
-+ retrieved += DEFAULT_AUX_MAX_DATA_SIZE) {
-+
-+ uint8_t offset = base_offset + retrieved;
-+
-+ struct aux_payload payloads[3] = {
-+ {
-+ .i2c_over_aux = true,
-+ .write = true,
-+ .address = DDC_EDID_SEGMENT_ADDRESS,
-+ .length = 1,
-+ .data = &segment },
-+ {
-+ .i2c_over_aux = true,
-+ .write = true,
-+ .address = address,
-+ .length = 1,
-+ .data = &offset },
-+ {
-+ .i2c_over_aux = true,
-+ .write = false,
-+ .address = address,
-+ .length = DEFAULT_AUX_MAX_DATA_SIZE,
-+ .data = &buf[retrieved] } };
-+
-+ if (segment == 0) {
-+ cmd.payloads = &payloads[1];
-+ cmd.number_of_payloads = 2;
-+ } else {
-+ cmd.payloads = payloads;
-+ cmd.number_of_payloads = 3;
-+ }
-+
-+ if (!dal_i2caux_submit_aux_command(
-+ dal_adapter_service_get_i2caux(ddc->as),
-+ ddc->ddc_pin,
-+ &cmd))
-+ /* cannot read, break*/
-+ break;
-+ }
-+
-+ /* Reset segment to 0. Needed by some panels */
-+ if (0 != segment) {
-+ struct aux_payload payloads[1] = { {
-+ .i2c_over_aux = true,
-+ .write = true,
-+ .address = DDC_EDID_SEGMENT_ADDRESS,
-+ .length = 1,
-+ .data = &segment } };
-+ bool result = false;
-+
-+ segment = 0;
-+
-+ cmd.number_of_payloads = ARRAY_SIZE(payloads);
-+ cmd.payloads = payloads;
-+
-+ result = dal_i2caux_submit_aux_command(
-+ dal_adapter_service_get_i2caux(ddc->as),
-+ ddc->ddc_pin,
-+ &cmd);
-+
-+ if (false == result)
-+ dal_logger_write(
-+ ddc->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_DISPLAY_CAPABILITY_SERVICE,
-+ "%s: Writing of EDID Segment (0x30) failed!\n",
-+ __func__);
-+ }
-+
-+ return retrieved;
-+}
-+
-+static uint8_t i2c_read_edid_block(
-+ struct ddc_service *ddc,
-+ uint8_t address,
-+ uint8_t index,
-+ uint8_t *buf)
-+{
-+ bool ret = false;
-+ uint8_t offset = (index % DDC_EDID_BLOCKS_PER_SEGMENT) *
-+ DDC_EDID_BLOCK_SIZE;
-+ uint8_t segment = index / DDC_EDID_BLOCKS_PER_SEGMENT;
-+
-+ struct i2c_command cmd = {
-+ .payloads = NULL,
-+ .number_of_payloads = 0,
-+ .engine = DDC_I2C_COMMAND_ENGINE,
-+ .speed = dal_adapter_service_get_sw_i2c_speed(ddc->as) };
-+
-+ struct i2c_payload payloads[3] = {
-+ {
-+ .write = true,
-+ .address = DDC_EDID_SEGMENT_ADDRESS,
-+ .length = 1,
-+ .data = &segment },
-+ {
-+ .write = true,
-+ .address = address,
-+ .length = 1,
-+ .data = &offset },
-+ {
-+ .write = false,
-+ .address = address,
-+ .length = DDC_EDID_BLOCK_SIZE,
-+ .data = buf } };
-+/*
-+ * Some I2C engines don't handle stop/start between write-offset and read-data
-+ * commands properly. For those displays, we have to force the newer E-DDC
-+ * behavior of repeated-start which can be enabled by runtime parameter. */
-+/* Originally implemented for OnLive using NXP receiver chip */
-+
-+ if (index == 0 && !ddc->flags.FORCE_READ_REPEATED_START) {
-+ /* base block, use use DDC2B, submit as 2 commands */
-+ cmd.payloads = &payloads[1];
-+ cmd.number_of_payloads = 1;
-+
-+ if (dal_i2caux_submit_i2c_command(
-+ dal_adapter_service_get_i2caux(ddc->as),
-+ ddc->ddc_pin,
-+ &cmd)) {
-+
-+ cmd.payloads = &payloads[2];
-+ cmd.number_of_payloads = 1;
-+
-+ ret = dal_i2caux_submit_i2c_command(
-+ dal_adapter_service_get_i2caux(ddc->as),
-+ ddc->ddc_pin,
-+ &cmd);
-+ }
-+
-+ } else {
-+ /*
-+ * extension block use E-DDC, submit as 1 command
-+ * or if repeated-start is forced by runtime parameter
-+ */
-+ if (segment != 0) {
-+ /* include segment offset in command*/
-+ cmd.payloads = payloads;
-+ cmd.number_of_payloads = 3;
-+ } else {
-+ /* we are reading first segment,
-+ * segment offset is not required */
-+ cmd.payloads = &payloads[1];
-+ cmd.number_of_payloads = 2;
-+ }
-+
-+ ret = dal_i2caux_submit_i2c_command(
-+ dal_adapter_service_get_i2caux(ddc->as),
-+ ddc->ddc_pin,
-+ &cmd);
-+ }
-+
-+ return ret ? DDC_EDID_BLOCK_SIZE : 0;
-+}
-+
-+static uint32_t query_edid_block(
-+ struct ddc_service *ddc,
-+ uint8_t address,
-+ uint8_t index,
-+ uint8_t *buf,
-+ uint32_t size)
-+{
-+ uint32_t size_retrieved = 0;
-+
-+ if (size < DDC_EDID_BLOCK_SIZE)
-+ return 0;
-+
-+ if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) {
-+
-+ ASSERT(index < 2);
-+ size_retrieved =
-+ aux_read_edid_block(ddc, address, index, buf);
-+ } else {
-+ size_retrieved =
-+ i2c_read_edid_block(ddc, address, index, buf);
-+ }
-+
-+ return size_retrieved;
-+}
-+
-+#define DDC_DPCD_EDID_CHECKSUM_WRITE_ADDRESS 0x261
-+#define DDC_TEST_ACK_ADDRESS 0x260
-+#define DDC_DPCD_EDID_TEST_ACK 0x04
-+#define DDC_DPCD_EDID_TEST_MASK 0x04
-+#define DDC_DPCD_TEST_REQUEST_ADDRESS 0x218
-+
-+static void write_dp_edid_checksum(
-+ struct ddc_service *ddc,
-+ uint8_t checksum)
-+{
-+ uint8_t dpcd_data;
-+
-+ dal_ddc_service_read_dpcd_data(
-+ ddc,
-+ DDC_DPCD_TEST_REQUEST_ADDRESS,
-+ &dpcd_data,
-+ 1);
-+
-+ if (dpcd_data & DDC_DPCD_EDID_TEST_MASK) {
-+
-+ dal_ddc_service_write_dpcd_data(
-+ ddc,
-+ DDC_DPCD_EDID_CHECKSUM_WRITE_ADDRESS,
-+ &checksum,
-+ 1);
-+
-+ dpcd_data = DDC_DPCD_EDID_TEST_ACK;
-+
-+ dal_ddc_service_write_dpcd_data(
-+ ddc,
-+ DDC_TEST_ACK_ADDRESS,
-+ &dpcd_data,
-+ 1);
-+ }
-+}
-+
-+uint32_t dal_ddc_service_edid_query(struct ddc_service *ddc)
-+{
-+ uint32_t bytes_read = 0;
-+ uint32_t ext_cnt = 0;
-+
-+ uint8_t address;
-+ uint32_t i;
-+
-+ for (address = DDC_EDID_ADDRESS_START;
-+ address <= DDC_EDID_ADDRESS_END; ++address) {
-+
-+ bytes_read = query_edid_block(
-+ ddc,
-+ address,
-+ 0,
-+ ddc->edid_buf,
-+ sizeof(ddc->edid_buf) - bytes_read);
-+
-+ if (bytes_read != DDC_EDID_BLOCK_SIZE)
-+ continue;
-+
-+ /* get the number of ext blocks*/
-+ ext_cnt = ddc->edid_buf[DDC_EDID_EXT_COUNT_OFFSET];
-+
-+ /* EDID 2.0, need to read 1 more block because EDID2.0 is
-+ * 256 byte in size*/
-+ if (ddc->edid_buf[DDC_EDID_20_SIGNATURE_OFFSET] ==
-+ DDC_EDID_20_SIGNATURE)
-+ ext_cnt = 1;
-+
-+ for (i = 0; i < ext_cnt; i++) {
-+ /* read additional ext blocks accordingly */
-+ bytes_read += query_edid_block(
-+ ddc,
-+ address,
-+ i+1,
-+ &ddc->edid_buf[bytes_read],
-+ sizeof(ddc->edid_buf) - bytes_read);
-+ }
-+
-+ /*this is special code path for DP compliance*/
-+ if (DDC_TRANSACTION_TYPE_I2C_OVER_AUX == ddc->transaction_type)
-+ write_dp_edid_checksum(
-+ ddc,
-+ ddc->edid_buf[(ext_cnt * DDC_EDID_BLOCK_SIZE) +
-+ DDC_EDID1X_CHECKSUM_OFFSET]);
-+
-+ /*remembers the address where we fetch the EDID from
-+ * for later signature check use */
-+ ddc->address = address;
-+
-+ break;/* already read edid, done*/
-+ }
-+
-+ ddc->edid_buf_len = bytes_read;
-+ return bytes_read;
-+}
-+
-+uint32_t dal_ddc_service_get_edid_buf_len(struct ddc_service *ddc)
-+{
-+ return ddc->edid_buf_len;
-+}
-+
-+void dal_ddc_service_get_edid_buf(struct ddc_service *ddc, uint8_t *edid_buf)
-+{
-+ dc_service_memmove(edid_buf,
-+ ddc->edid_buf, ddc->edid_buf_len);
-+}
-+
-+void dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
-+ struct ddc_service *ddc,
-+ struct display_sink_capability *sink_cap)
-+{
-+ uint8_t i;
-+ bool is_valid_hdmi_signature;
-+ enum display_dongle_type *dongle = &sink_cap->dongle_type;
-+ uint8_t type2_dongle_buf[DP_ADAPTOR_TYPE2_SIZE];
-+ bool is_type2_dongle = false;
-+ struct dp_hdmi_dongle_signature_data *dongle_signature;
-+
-+ /* Assume we have no valid DP passive dongle connected */
-+ *dongle = DISPLAY_DONGLE_NONE;
-+ sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_HDMI_SAFE_MAX_TMDS_CLK;
-+
-+ /* Read DP-HDMI dongle I2c (no response interpreted as DP-DVI dongle)*/
-+ if (!i2c_read(
-+ ddc,
-+ DP_HDMI_DONGLE_ADDRESS,
-+ type2_dongle_buf,
-+ sizeof(type2_dongle_buf))) {
-+ dal_logger_write(ddc->ctx->logger,
-+ LOG_MAJOR_DCS,
-+ LOG_MINOR_DCS_DONGLE_DETECTION,
-+ "Detected DP-DVI dongle.\n");
-+ *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
-+ sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK;
-+ return;
-+ }
-+
-+ /* Check if Type 2 dongle.*/
-+ if (type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_ID] == DP_ADAPTOR_TYPE2_ID)
-+ is_type2_dongle = true;
-+
-+ dongle_signature =
-+ (struct dp_hdmi_dongle_signature_data *)type2_dongle_buf;
-+
-+ is_valid_hdmi_signature = true;
-+
-+ /* Check EOT */
-+ if (dongle_signature->eot != DP_HDMI_DONGLE_SIGNATURE_EOT) {
-+ is_valid_hdmi_signature = false;
-+ }
-+
-+ /* Check signature */
-+ for (i = 0; i < sizeof(dongle_signature->id); ++i) {
-+ /* If its not the right signature,
-+ * skip mismatch in subversion byte.*/
-+ if (dongle_signature->id[i] !=
-+ dp_hdmi_dongle_signature_str[i] && i != 3) {
-+
-+ if (is_type2_dongle) {
-+ is_valid_hdmi_signature = false;
-+ break;
-+ }
-+
-+ }
-+ }
-+
-+ if (is_type2_dongle) {
-+ uint32_t max_tmds_clk =
-+ type2_dongle_buf[DP_ADAPTOR_TYPE2_REG_MAX_TMDS_CLK];
-+
-+ max_tmds_clk = max_tmds_clk * 2 + max_tmds_clk / 2;
-+
-+ if (0 == max_tmds_clk ||
-+ max_tmds_clk < DP_ADAPTOR_TYPE2_MIN_TMDS_CLK ||
-+ max_tmds_clk > DP_ADAPTOR_TYPE2_MAX_TMDS_CLK) {
-+ dal_logger_write(ddc->ctx->logger,
-+ LOG_MAJOR_DCS,
-+ LOG_MINOR_DCS_DONGLE_DETECTION,
-+ "Invalid Maximum TMDS clock");
-+ *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE;
-+ } else {
-+ if (is_valid_hdmi_signature == true) {
-+ *dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
-+ dal_logger_write(ddc->ctx->logger,
-+ LOG_MAJOR_DCS,
-+ LOG_MINOR_DCS_DONGLE_DETECTION,
-+ "Detected Type 2 DP-HDMI Maximum TMDS "
-+ "clock, max TMDS clock: %d MHz",
-+ max_tmds_clk);
-+ } else {
-+ *dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
-+ dal_logger_write(ddc->ctx->logger,
-+ LOG_MAJOR_DCS,
-+ LOG_MINOR_DCS_DONGLE_DETECTION,
-+ "Detected Type 2 DP-HDMI (no valid HDMI"
-+ " signature) Maximum TMDS clock, max "
-+ "TMDS clock: %d MHz",
-+ max_tmds_clk);
-+ }
-+
-+ /* Multiply by 1000 to convert to kHz. */
-+ sink_cap->max_hdmi_pixel_clock =
-+ max_tmds_clk * 1000;
-+ }
-+
-+ } else {
-+ if (is_valid_hdmi_signature == true) {
-+ dal_logger_write(ddc->ctx->logger,
-+ LOG_MAJOR_DCS,
-+ LOG_MINOR_DCS_DONGLE_DETECTION,
-+ "Detected Type 1 DP-HDMI dongle.\n");
-+ *dongle = DISPLAY_DONGLE_DP_HDMI_DONGLE;
-+ }
-+ else {
-+ dal_logger_write(ddc->ctx->logger,
-+ LOG_MAJOR_DCS,
-+ LOG_MINOR_DCS_DONGLE_DETECTION,
-+ "Detected Type 1 DP-HDMI dongle (no valid HDMI "
-+ "signature).\n");
-+
-+ *dongle = DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE;
-+ }
-+ }
-+
-+ return;
-+}
-+
-+enum {
-+ DP_SINK_CAP_SIZE =
-+ DPCD_ADDRESS_EDP_CONFIG_CAP - DPCD_ADDRESS_DPCD_REV + 1
-+};
-+
-+bool dal_ddc_service_query_ddc_data(
-+ struct ddc_service *ddc,
-+ uint32_t address,
-+ uint8_t *write_buf,
-+ uint32_t write_size,
-+ uint8_t *read_buf,
-+ uint32_t read_size)
-+{
-+ bool ret;
-+ uint32_t payload_size =
-+ dal_ddc_service_is_in_aux_transaction_mode(ddc) ?
-+ DEFAULT_AUX_MAX_DATA_SIZE : EDID_SEGMENT_SIZE;
-+
-+ uint32_t write_payloads =
-+ (write_size + payload_size - 1) / payload_size;
-+
-+ uint32_t read_payloads =
-+ (read_size + payload_size - 1) / payload_size;
-+
-+ uint32_t payloads_num = write_payloads + read_payloads;
-+
-+ if (write_size > EDID_SEGMENT_SIZE || read_size > EDID_SEGMENT_SIZE)
-+ return false;
-+
-+ /*TODO: len of payload data for i2c and aux is uint8!!!!,
-+ * but we want to read 256 over i2c!!!!*/
-+ if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) {
-+
-+ struct aux_payloads *payloads =
-+ dal_ddc_aux_payloads_create(ddc->ctx, payloads_num);
-+
-+ struct aux_command command = {
-+ .payloads = dal_ddc_aux_payloads_get(payloads),
-+ .number_of_payloads = 0,
-+ .defer_delay = get_defer_delay(ddc),
-+ .max_defer_write_retry = 0 };
-+
-+ dal_ddc_aux_payloads_add(
-+ payloads, address, write_size, write_buf, true);
-+
-+ dal_ddc_aux_payloads_add(
-+ payloads, address, read_size, read_buf, false);
-+
-+ command.number_of_payloads =
-+ dal_ddc_aux_payloads_get_count(payloads);
-+
-+ ret = dal_i2caux_submit_aux_command(
-+ dal_adapter_service_get_i2caux(ddc->as),
-+ ddc->ddc_pin,
-+ &command);
-+
-+ dal_ddc_aux_payloads_destroy(&payloads);
-+
-+ } else {
-+ struct i2c_payloads *payloads =
-+ dal_ddc_i2c_payloads_create(ddc->ctx, payloads_num);
-+
-+ struct i2c_command command = {
-+ .payloads = dal_ddc_i2c_payloads_get(payloads),
-+ .number_of_payloads = 0,
-+ .engine = DDC_I2C_COMMAND_ENGINE,
-+ .speed =
-+ dal_adapter_service_get_sw_i2c_speed(ddc->as) };
-+
-+ dal_ddc_i2c_payloads_add(
-+ payloads, address, write_size, write_buf, true);
-+
-+ dal_ddc_i2c_payloads_add(
-+ payloads, address, read_size, read_buf, false);
-+
-+ command.number_of_payloads =
-+ dal_ddc_i2c_payloads_get_count(payloads);
-+
-+ ret = dal_i2caux_submit_i2c_command(
-+ dal_adapter_service_get_i2caux(ddc->as),
-+ ddc->ddc_pin,
-+ &command);
-+
-+ dal_ddc_i2c_payloads_destroy(&payloads);
-+ }
-+
-+ return ret;
-+}
-+
-+bool dal_ddc_service_get_dp_receiver_id_info(
-+ struct ddc_service *ddc,
-+ struct dp_receiver_id_info *info)
-+{
-+ if (!info)
-+ return false;
-+
-+ *info = ddc->dp_receiver_id_info;
-+ return true;
-+}
-+
-+enum ddc_result dal_ddc_service_read_dpcd_data(
-+ struct ddc_service *ddc,
-+ uint32_t address,
-+ uint8_t *data,
-+ uint32_t len)
-+{
-+ struct aux_payload read_payload = {
-+ .i2c_over_aux = false,
-+ .write = false,
-+ .address = address,
-+ .length = len,
-+ .data = data,
-+ };
-+ struct aux_command command = {
-+ .payloads = &read_payload,
-+ .number_of_payloads = 1,
-+ .defer_delay = 0,
-+ .max_defer_write_retry = 0,
-+ };
-+
-+ if (len > DEFAULT_AUX_MAX_DATA_SIZE) {
-+ BREAK_TO_DEBUGGER();
-+ return DDC_RESULT_FAILED_INVALID_OPERATION;
-+ }
-+
-+ if (dal_i2caux_submit_aux_command(
-+ dal_adapter_service_get_i2caux(ddc->as),
-+ ddc->ddc_pin,
-+ &command))
-+ return DDC_RESULT_SUCESSFULL;
-+
-+ return DDC_RESULT_FAILED_OPERATION;
-+}
-+
-+enum ddc_result dal_ddc_service_write_dpcd_data(
-+ struct ddc_service *ddc,
-+ uint32_t address,
-+ const uint8_t *data,
-+ uint32_t len)
-+{
-+ struct aux_payload write_payload = {
-+ .i2c_over_aux = false,
-+ .write = true,
-+ .address = address,
-+ .length = len,
-+ .data = (uint8_t *)data,
-+ };
-+ struct aux_command command = {
-+ .payloads = &write_payload,
-+ .number_of_payloads = 1,
-+ .defer_delay = 0,
-+ .max_defer_write_retry = 0,
-+ };
-+
-+ if (len > DEFAULT_AUX_MAX_DATA_SIZE) {
-+ BREAK_TO_DEBUGGER();
-+ return DDC_RESULT_FAILED_INVALID_OPERATION;
-+ }
-+
-+ if (dal_i2caux_submit_aux_command(
-+ dal_adapter_service_get_i2caux(ddc->as),
-+ ddc->ddc_pin,
-+ &command))
-+ return DDC_RESULT_SUCESSFULL;
-+
-+ return DDC_RESULT_FAILED_OPERATION;
-+}
-+
-+/*test only function*/
-+void dal_ddc_service_set_ddc_pin(
-+ struct ddc_service *ddc_service,
-+ struct ddc *ddc)
-+{
-+ ddc_service->ddc_pin = ddc;
-+}
-+
-+struct ddc *dal_ddc_service_get_ddc_pin(struct ddc_service *ddc_service)
-+{
-+ return ddc_service->ddc_pin;
-+}
-+
-+
-+void dal_ddc_service_reset_dp_receiver_id_info(struct ddc_service *ddc_service)
-+{
-+ dc_service_memset(&ddc_service->dp_receiver_id_info,
-+ 0, sizeof(struct dp_receiver_id_info));
-+}
-+
-+void dal_ddc_service_write_scdc_data(struct ddc_service *ddc_service,
-+ uint32_t pix_clk,
-+ bool lte_340_scramble)
-+{
-+ bool over_340_mhz = pix_clk > 340000 ? 1 : 0;
-+ uint8_t slave_address = HDMI_SCDC_ADDRESS;
-+ uint8_t offset = HDMI_SCDC_SINK_VERSION;
-+ uint8_t sink_version = 0;
-+ uint8_t write_buffer[2] = {0};
-+ /*Lower than 340 Scramble bit from SCDC caps*/
-+
-+ dal_ddc_service_query_ddc_data(ddc_service, slave_address, &offset,
-+ sizeof(offset), &sink_version, sizeof(sink_version));
-+ if (sink_version == 1) {
-+ /*Source Version = 1*/
-+ write_buffer[0] = HDMI_SCDC_SOURCE_VERSION;
-+ write_buffer[1] = 1;
-+ dal_ddc_service_query_ddc_data(ddc_service, slave_address,
-+ write_buffer, sizeof(write_buffer), NULL, 0);
-+ /*Read Request from SCDC caps*/
-+ }
-+ write_buffer[0] = HDMI_SCDC_TMDS_CONFIG;
-+
-+ if (over_340_mhz)
-+ {
-+ write_buffer[1] = 3;
-+ }
-+ else if (lte_340_scramble)
-+ {
-+ write_buffer[1] = 1;
-+ }
-+ else
-+ {
-+ write_buffer[1] = 0;
-+ }
-+ dal_ddc_service_query_ddc_data(ddc_service, slave_address, write_buffer,
-+ sizeof(write_buffer), NULL, 0);
-+}
-+
-+void dal_ddc_service_read_scdc_data(struct ddc_service *ddc_service)
-+{
-+ uint8_t slave_address = HDMI_SCDC_ADDRESS;
-+ uint8_t offset = HDMI_SCDC_TMDS_CONFIG;
-+ uint8_t tmds_config = 0;
-+
-+ dal_ddc_service_query_ddc_data(ddc_service, slave_address, &offset,
-+ sizeof(offset), &tmds_config, sizeof(tmds_config));
-+ if (tmds_config & 0x1){
-+ union hdmi_scdc_status_flags_data status_data = {{0}};
-+ uint8_t scramble_status = 0;
-+
-+ offset = HDMI_SCDC_SCRAMBLER_STATUS;
-+ dal_ddc_service_query_ddc_data(ddc_service, slave_address,
-+ &offset, sizeof(offset),&scramble_status,
-+ sizeof(scramble_status));
-+ offset = HDMI_SCDC_STATUS_FLAGS;
-+ dal_ddc_service_query_ddc_data(ddc_service, slave_address,
-+ &offset, sizeof(offset),status_data.byte,
-+ sizeof(status_data.byte));
-+ }
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dcs/ddc_service.h b/drivers/gpu/drm/amd/dal/dc/dcs/ddc_service.h
-new file mode 100644
-index 0000000..e5217b7
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dcs/ddc_service.h
-@@ -0,0 +1,38 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DDC_SERVICE_H__
-+#define __DAL_DDC_SERVICE_H__
-+
-+#include "include/ddc_service_types.h"
-+
-+void dal_ddc_service_set_ddc_pin(
-+ struct ddc_service *ddc_service,
-+ struct ddc *ddc);
-+
-+struct ddc *dal_ddc_service_get_ddc_pin(struct ddc_service *ddc_service);
-+void dal_ddc_service_reset_dp_receiver_id_info(struct ddc_service *ddc_service);
-+
-+#endif /* __DAL_DDC_SERVICE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/Makefile b/drivers/gpu/drm/amd/dal/dc/gpio/Makefile
-new file mode 100644
-index 0000000..7380910
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/Makefile
-@@ -0,0 +1,24 @@
-+#
-+# Makefile for the 'gpio' sub-component of DAL.
-+# It provides the control and status of HW GPIO pins.
-+
-+GPIO = ddc.o dvo.o gpio_base.o gpio_service.o hw_ddc.o hw_dvo.o hw_factory.o \
-+ hw_gpio.o hw_gpio_pad.o hw_gpio_pin.o hw_hpd.o hw_translate.o irq.o
-+
-+AMD_DAL_GPIO = $(addprefix $(AMDDALPATH)/dc/gpio/,$(GPIO))
-+
-+AMD_DAL_FILES += $(AMD_DAL_GPIO)
-+
-+
-+###############################################################################
-+# DCE 11x
-+###############################################################################
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_0
-+GPIO_DCE110 = hw_translate_dce110.o hw_factory_dce110.o hw_hpd_dce110.o \
-+ hw_ddc_dce110.o
-+
-+AMD_DAL_GPIO_DCE110 = $(addprefix $(AMDDALPATH)/dc/gpio/dce110/,$(GPIO_DCE110))
-+
-+AMD_DAL_FILES += $(AMD_DAL_GPIO_DCE110)
-+endif
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.c b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.c
-new file mode 100644
-index 0000000..f026464
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.c
-@@ -0,0 +1,883 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/gpio_types.h"
-+#include "../hw_gpio_pin.h"
-+#include "../hw_gpio.h"
-+#include "../hw_ddc.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+#include "hw_ddc_dce110.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#define ADDR_DDC_SETUP pin->addr.dc_i2c_ddc_setup
-+/*
-+ * This unit
-+ */
-+static void destruct(
-+ struct hw_ddc_dce110 *pin)
-+{
-+ dal_hw_ddc_destruct(&pin->base);
-+}
-+
-+static void destroy(
-+ struct hw_gpio_pin **ptr)
-+{
-+ struct hw_ddc_dce110 *pin = DDC_DCE110_FROM_BASE(*ptr);
-+
-+ destruct(pin);
-+
-+ dc_service_free((*ptr)->ctx, pin);
-+
-+ *ptr = NULL;
-+}
-+
-+struct hw_ddc_dce110_init {
-+ struct hw_gpio_pin_reg hw_gpio_data_reg;
-+ struct hw_ddc_mask hw_ddc_mask;
-+ struct hw_ddc_dce110_addr hw_ddc_dce110_addr;
-+};
-+
-+static const struct hw_ddc_dce110_init
-+ hw_ddc_dce110_init_data[GPIO_DDC_LINE_COUNT] = {
-+ /* GPIO_DDC_LINE_DDC1 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDC1_MASK,
-+ DC_GPIO_DDC1_MASK__DC_GPIO_DDC1DATA_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC1_A,
-+ DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC1_EN,
-+ DC_GPIO_DDC1_EN__DC_GPIO_DDC1DATA_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC1_Y,
-+ DC_GPIO_DDC1_Y__DC_GPIO_DDC1DATA_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDC1_MASK__DC_GPIO_DDC1DATA_MASK_MASK,
-+ DC_GPIO_DDC1_MASK__DC_GPIO_DDC1DATA_PD_EN_MASK,
-+ DC_GPIO_DDC1_MASK__DC_GPIO_DDC1DATA_RECV_MASK,
-+ DC_GPIO_DDC1_MASK__AUX_PAD1_MODE_MASK,
-+ DC_GPIO_DDC1_MASK__AUX1_POL_MASK,
-+ DC_GPIO_DDC1_MASK__DC_GPIO_DDC1CLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDC1_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_DDC2 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDC2_MASK,
-+ DC_GPIO_DDC2_MASK__DC_GPIO_DDC2DATA_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC2_A,
-+ DC_GPIO_DDC2_A__DC_GPIO_DDC2DATA_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC2_EN,
-+ DC_GPIO_DDC2_EN__DC_GPIO_DDC2DATA_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC2_Y,
-+ DC_GPIO_DDC2_Y__DC_GPIO_DDC2DATA_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDC2_MASK__DC_GPIO_DDC2DATA_MASK_MASK,
-+ DC_GPIO_DDC2_MASK__DC_GPIO_DDC2DATA_PD_EN_MASK,
-+ DC_GPIO_DDC2_MASK__DC_GPIO_DDC2DATA_RECV_MASK,
-+ DC_GPIO_DDC2_MASK__AUX_PAD2_MODE_MASK,
-+ DC_GPIO_DDC2_MASK__AUX2_POL_MASK,
-+ DC_GPIO_DDC2_MASK__DC_GPIO_DDC2CLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDC2_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_DDC3 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDC3_MASK,
-+ DC_GPIO_DDC3_MASK__DC_GPIO_DDC3DATA_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC3_A,
-+ DC_GPIO_DDC3_A__DC_GPIO_DDC3DATA_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC3_EN,
-+ DC_GPIO_DDC3_EN__DC_GPIO_DDC3DATA_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC3_Y,
-+ DC_GPIO_DDC3_Y__DC_GPIO_DDC3DATA_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDC3_MASK__DC_GPIO_DDC3DATA_MASK_MASK,
-+ DC_GPIO_DDC3_MASK__DC_GPIO_DDC3DATA_PD_EN_MASK,
-+ DC_GPIO_DDC3_MASK__DC_GPIO_DDC3DATA_RECV_MASK,
-+ DC_GPIO_DDC3_MASK__AUX_PAD3_MODE_MASK,
-+ DC_GPIO_DDC3_MASK__AUX3_POL_MASK,
-+ DC_GPIO_DDC3_MASK__DC_GPIO_DDC3CLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDC3_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_DDC4 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDC4_MASK,
-+ DC_GPIO_DDC4_MASK__DC_GPIO_DDC4DATA_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC4_A,
-+ DC_GPIO_DDC4_A__DC_GPIO_DDC4DATA_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC4_EN,
-+ DC_GPIO_DDC4_EN__DC_GPIO_DDC4DATA_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC4_Y,
-+ DC_GPIO_DDC4_Y__DC_GPIO_DDC4DATA_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDC4_MASK__DC_GPIO_DDC4DATA_MASK_MASK,
-+ DC_GPIO_DDC4_MASK__DC_GPIO_DDC4DATA_PD_EN_MASK,
-+ DC_GPIO_DDC4_MASK__DC_GPIO_DDC4DATA_RECV_MASK,
-+ DC_GPIO_DDC4_MASK__AUX_PAD4_MODE_MASK,
-+ DC_GPIO_DDC4_MASK__AUX4_POL_MASK,
-+ DC_GPIO_DDC4_MASK__DC_GPIO_DDC4CLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDC4_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_DDC5 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDC5_MASK,
-+ DC_GPIO_DDC5_MASK__DC_GPIO_DDC5DATA_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC5_A,
-+ DC_GPIO_DDC5_A__DC_GPIO_DDC5DATA_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC5_EN,
-+ DC_GPIO_DDC5_EN__DC_GPIO_DDC5DATA_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC5_Y,
-+ DC_GPIO_DDC5_Y__DC_GPIO_DDC5DATA_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDC5_MASK__DC_GPIO_DDC5DATA_MASK_MASK,
-+ DC_GPIO_DDC5_MASK__DC_GPIO_DDC5DATA_PD_EN_MASK,
-+ DC_GPIO_DDC5_MASK__DC_GPIO_DDC5DATA_RECV_MASK,
-+ DC_GPIO_DDC5_MASK__AUX_PAD5_MODE_MASK,
-+ DC_GPIO_DDC5_MASK__AUX5_POL_MASK,
-+ DC_GPIO_DDC5_MASK__DC_GPIO_DDC5CLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDC5_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_DDC6 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDC6_MASK,
-+ DC_GPIO_DDC6_MASK__DC_GPIO_DDC6DATA_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC6_A,
-+ DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC6_EN,
-+ DC_GPIO_DDC6_EN__DC_GPIO_DDC6DATA_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC6_Y,
-+ DC_GPIO_DDC6_Y__DC_GPIO_DDC6DATA_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDC6_MASK__DC_GPIO_DDC6DATA_MASK_MASK,
-+ DC_GPIO_DDC6_MASK__DC_GPIO_DDC6DATA_PD_EN_MASK,
-+ DC_GPIO_DDC6_MASK__DC_GPIO_DDC6DATA_RECV_MASK,
-+ DC_GPIO_DDC6_MASK__AUX_PAD6_MODE_MASK,
-+ DC_GPIO_DDC6_MASK__AUX6_POL_MASK,
-+ DC_GPIO_DDC6_MASK__DC_GPIO_DDC6CLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDC6_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_DDC_VGA */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDCVGA_MASK,
-+ DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGADATA_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDCVGA_A,
-+ DC_GPIO_DDCVGA_A__DC_GPIO_DDCVGADATA_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDCVGA_EN,
-+ DC_GPIO_DDCVGA_EN__DC_GPIO_DDCVGADATA_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDCVGA_Y,
-+ DC_GPIO_DDCVGA_Y__DC_GPIO_DDCVGADATA_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGADATA_MASK_MASK,
-+ DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGADATA_PD_EN_MASK,
-+ DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGADATA_RECV_MASK,
-+ DC_GPIO_DDCVGA_MASK__AUX_PADVGA_MODE_MASK,
-+ DC_GPIO_DDCVGA_MASK__AUXVGA_POL_MASK,
-+ DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGACLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDCVGA_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_I2CPAD */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_I2CPAD_MASK,
-+ DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_I2CPAD_A,
-+ DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_I2CPAD_EN,
-+ DC_GPIO_I2CPAD_EN__DC_GPIO_SDA_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_I2CPAD_Y,
-+ DC_GPIO_I2CPAD_Y__DC_GPIO_SDA_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_MASK_MASK,
-+ DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_PD_DIS_MASK,
-+ DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_RECV_MASK,
-+ 0,
-+ 0,
-+ 0
-+ },
-+ {
-+ 0
-+ }
-+ }
-+};
-+
-+static const struct hw_ddc_dce110_init
-+ hw_ddc_dce110_init_clock[GPIO_DDC_LINE_COUNT] = {
-+ /* GPIO_DDC_LINE_DDC1 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDC1_MASK,
-+ DC_GPIO_DDC1_MASK__DC_GPIO_DDC1CLK_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC1_A,
-+ DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC1_EN,
-+ DC_GPIO_DDC1_EN__DC_GPIO_DDC1CLK_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC1_Y,
-+ DC_GPIO_DDC1_Y__DC_GPIO_DDC1CLK_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDC1_MASK__DC_GPIO_DDC1CLK_MASK_MASK,
-+ DC_GPIO_DDC1_MASK__DC_GPIO_DDC1CLK_PD_EN_MASK,
-+ DC_GPIO_DDC1_MASK__DC_GPIO_DDC1CLK_RECV_MASK,
-+ DC_GPIO_DDC1_MASK__AUX_PAD1_MODE_MASK,
-+ DC_GPIO_DDC1_MASK__AUX1_POL_MASK,
-+ DC_GPIO_DDC1_MASK__DC_GPIO_DDC1CLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDC1_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_DDC2 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDC2_MASK,
-+ DC_GPIO_DDC2_MASK__DC_GPIO_DDC2CLK_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC2_A,
-+ DC_GPIO_DDC2_A__DC_GPIO_DDC2CLK_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC2_EN,
-+ DC_GPIO_DDC2_EN__DC_GPIO_DDC2CLK_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC2_Y,
-+ DC_GPIO_DDC2_Y__DC_GPIO_DDC2CLK_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDC2_MASK__DC_GPIO_DDC2CLK_MASK_MASK,
-+ DC_GPIO_DDC2_MASK__DC_GPIO_DDC2CLK_PD_EN_MASK,
-+ DC_GPIO_DDC2_MASK__DC_GPIO_DDC2CLK_RECV_MASK,
-+ DC_GPIO_DDC2_MASK__AUX_PAD2_MODE_MASK,
-+ DC_GPIO_DDC2_MASK__AUX2_POL_MASK,
-+ DC_GPIO_DDC2_MASK__DC_GPIO_DDC2CLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDC2_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_DDC3 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDC3_MASK,
-+ DC_GPIO_DDC3_MASK__DC_GPIO_DDC3CLK_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC3_A,
-+ DC_GPIO_DDC3_A__DC_GPIO_DDC3CLK_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC3_EN,
-+ DC_GPIO_DDC3_EN__DC_GPIO_DDC3CLK_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC3_Y,
-+ DC_GPIO_DDC3_Y__DC_GPIO_DDC3CLK_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDC3_MASK__DC_GPIO_DDC3CLK_MASK_MASK,
-+ DC_GPIO_DDC3_MASK__DC_GPIO_DDC3CLK_PD_EN_MASK,
-+ DC_GPIO_DDC3_MASK__DC_GPIO_DDC3CLK_RECV_MASK,
-+ DC_GPIO_DDC3_MASK__AUX_PAD3_MODE_MASK,
-+ DC_GPIO_DDC3_MASK__AUX3_POL_MASK,
-+ DC_GPIO_DDC3_MASK__DC_GPIO_DDC3CLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDC3_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_DDC4 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDC4_MASK,
-+ DC_GPIO_DDC4_MASK__DC_GPIO_DDC4CLK_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC4_A,
-+ DC_GPIO_DDC4_A__DC_GPIO_DDC4CLK_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC4_EN,
-+ DC_GPIO_DDC4_EN__DC_GPIO_DDC4CLK_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC4_Y,
-+ DC_GPIO_DDC4_Y__DC_GPIO_DDC4CLK_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDC4_MASK__DC_GPIO_DDC4CLK_MASK_MASK,
-+ DC_GPIO_DDC4_MASK__DC_GPIO_DDC4CLK_PD_EN_MASK,
-+ DC_GPIO_DDC4_MASK__DC_GPIO_DDC4CLK_RECV_MASK,
-+ DC_GPIO_DDC4_MASK__AUX_PAD4_MODE_MASK,
-+ DC_GPIO_DDC4_MASK__AUX4_POL_MASK,
-+ DC_GPIO_DDC4_MASK__DC_GPIO_DDC4CLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDC4_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_DDC5 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDC5_MASK,
-+ DC_GPIO_DDC5_MASK__DC_GPIO_DDC5CLK_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC5_A,
-+ DC_GPIO_DDC5_A__DC_GPIO_DDC5CLK_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC5_EN,
-+ DC_GPIO_DDC5_EN__DC_GPIO_DDC5CLK_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC5_Y,
-+ DC_GPIO_DDC5_Y__DC_GPIO_DDC5CLK_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDC5_MASK__DC_GPIO_DDC5CLK_MASK_MASK,
-+ DC_GPIO_DDC5_MASK__DC_GPIO_DDC5CLK_PD_EN_MASK,
-+ DC_GPIO_DDC5_MASK__DC_GPIO_DDC5CLK_RECV_MASK,
-+ DC_GPIO_DDC5_MASK__AUX_PAD5_MODE_MASK,
-+ DC_GPIO_DDC5_MASK__AUX5_POL_MASK,
-+ DC_GPIO_DDC5_MASK__DC_GPIO_DDC5CLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDC5_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_DDC6 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDC6_MASK,
-+ DC_GPIO_DDC6_MASK__DC_GPIO_DDC6CLK_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC6_A,
-+ DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC6_EN,
-+ DC_GPIO_DDC6_EN__DC_GPIO_DDC6CLK_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDC6_Y,
-+ DC_GPIO_DDC6_Y__DC_GPIO_DDC6CLK_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDC6_MASK__DC_GPIO_DDC6CLK_MASK_MASK,
-+ DC_GPIO_DDC6_MASK__DC_GPIO_DDC6CLK_PD_EN_MASK,
-+ DC_GPIO_DDC6_MASK__DC_GPIO_DDC6CLK_RECV_MASK,
-+ DC_GPIO_DDC6_MASK__AUX_PAD6_MODE_MASK,
-+ DC_GPIO_DDC6_MASK__AUX6_POL_MASK,
-+ DC_GPIO_DDC6_MASK__DC_GPIO_DDC6CLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDC6_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_DDC_VGA */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_DDCVGA_MASK,
-+ DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGACLK_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDCVGA_A,
-+ DC_GPIO_DDCVGA_A__DC_GPIO_DDCVGACLK_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDCVGA_EN,
-+ DC_GPIO_DDCVGA_EN__DC_GPIO_DDCVGACLK_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_DDCVGA_Y,
-+ DC_GPIO_DDCVGA_Y__DC_GPIO_DDCVGACLK_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGACLK_MASK_MASK,
-+ DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGADATA_PD_EN_MASK,
-+ DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGACLK_RECV_MASK,
-+ DC_GPIO_DDCVGA_MASK__AUX_PADVGA_MODE_MASK,
-+ DC_GPIO_DDCVGA_MASK__AUXVGA_POL_MASK,
-+ DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGACLK_STR_MASK
-+ },
-+ {
-+ mmDC_I2C_DDCVGA_SETUP
-+ }
-+ },
-+ /* GPIO_DDC_LINE_I2CPAD */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_I2CPAD_MASK,
-+ DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_I2CPAD_A,
-+ DC_GPIO_I2CPAD_A__DC_GPIO_SCL_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_I2CPAD_EN,
-+ DC_GPIO_I2CPAD_EN__DC_GPIO_SCL_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_I2CPAD_Y,
-+ DC_GPIO_I2CPAD_Y__DC_GPIO_SCL_Y_MASK
-+ }
-+ },
-+ {
-+ DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_MASK_MASK,
-+ DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_PD_DIS_MASK,
-+ DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_RECV_MASK,
-+ 0,
-+ 0,
-+ 0
-+ },
-+ {
-+ 0
-+ }
-+ }
-+};
-+
-+static void setup_i2c_polling(
-+ struct dc_context *ctx,
-+ const uint32_t addr,
-+ bool enable_detect,
-+ bool detect_mode)
-+{
-+ uint32_t value;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ enable_detect,
-+ DC_I2C_DDC1_SETUP,
-+ DC_I2C_DDC1_ENABLE);
-+
-+ set_reg_field_value(
-+ value,
-+ enable_detect,
-+ DC_I2C_DDC1_SETUP,
-+ DC_I2C_DDC1_EDID_DETECT_ENABLE);
-+
-+ if (enable_detect)
-+ set_reg_field_value(
-+ value,
-+ detect_mode,
-+ DC_I2C_DDC1_SETUP,
-+ DC_I2C_DDC1_EDID_DETECT_MODE);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+static enum gpio_result set_config(
-+ struct hw_gpio_pin *ptr,
-+ const struct gpio_config_data *config_data)
-+{
-+ struct hw_ddc_dce110 *pin = DDC_DCE110_FROM_BASE(ptr);
-+ struct hw_gpio *hw_gpio = NULL;
-+ uint32_t addr;
-+ uint32_t regval;
-+ uint32_t ddc_data_pd_en = 0;
-+ uint32_t ddc_clk_pd_en = 0;
-+ uint32_t aux_pad_mode = 0;
-+
-+ hw_gpio = &pin->base.base;
-+
-+ if (hw_gpio == NULL) {
-+ ASSERT_CRITICAL(false);
-+ return GPIO_RESULT_NULL_HANDLE;
-+ }
-+
-+ /* switch dual mode GPIO to I2C/AUX mode */
-+
-+ addr = hw_gpio->pin_reg.DC_GPIO_DATA_MASK.addr;
-+
-+ regval = dal_read_reg(ptr->ctx, addr);
-+
-+ ddc_data_pd_en = get_reg_field_value(
-+ regval,
-+ DC_GPIO_DDC1_MASK,
-+ DC_GPIO_DDC1DATA_PD_EN);
-+
-+ ddc_clk_pd_en = get_reg_field_value(
-+ regval,
-+ DC_GPIO_DDC1_MASK,
-+ DC_GPIO_DDC1CLK_PD_EN);
-+
-+ aux_pad_mode = get_reg_field_value(
-+ regval,
-+ DC_GPIO_DDC1_MASK,
-+ AUX_PAD1_MODE);
-+
-+ switch (config_data->config.ddc.type) {
-+ case GPIO_DDC_CONFIG_TYPE_MODE_I2C:
-+ /* On plug-in, there is a transient level on the pad
-+ * which must be discharged through the internal pull-down.
-+ * Enable internal pull-down, 2.5msec discharge time
-+ * is required for detection of AUX mode */
-+ if (hw_gpio->base.en != GPIO_DDC_LINE_VIP_PAD) {
-+ if (!ddc_data_pd_en || !ddc_clk_pd_en) {
-+ set_reg_field_value(
-+ regval,
-+ 1,
-+ DC_GPIO_DDC1_MASK,
-+ DC_GPIO_DDC1DATA_PD_EN);
-+
-+ set_reg_field_value(
-+ regval,
-+ 1,
-+ DC_GPIO_DDC1_MASK,
-+ DC_GPIO_DDC1CLK_PD_EN);
-+
-+ dal_write_reg(ptr->ctx, addr, regval);
-+
-+ if (config_data->type ==
-+ GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
-+ /* should not affect normal I2C R/W */
-+ /* [anaumov] in DAL2, there was
-+ * dc_service_delay_in_microseconds(2500); */
-+ dc_service_sleep_in_milliseconds(ptr->ctx, 3);
-+ }
-+ } else {
-+ uint32_t reg2 = regval;
-+ uint32_t sda_pd_dis = 0;
-+ uint32_t scl_pd_dis = 0;
-+
-+ sda_pd_dis = get_reg_field_value(
-+ reg2,
-+ DC_GPIO_I2CPAD_MASK,
-+ DC_GPIO_SDA_PD_DIS);
-+
-+ scl_pd_dis = get_reg_field_value(
-+ reg2,
-+ DC_GPIO_I2CPAD_MASK,
-+ DC_GPIO_SCL_PD_DIS);
-+
-+ if (sda_pd_dis) {
-+ sda_pd_dis = 0;
-+
-+ dal_write_reg(ptr->ctx, addr, reg2);
-+
-+ if (config_data->type ==
-+ GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
-+ /* should not affect normal I2C R/W */
-+ /* [anaumov] in DAL2, there was
-+ * dc_service_delay_in_microseconds(2500); */
-+ dc_service_sleep_in_milliseconds(ptr->ctx, 3);
-+ }
-+
-+ if (!scl_pd_dis) {
-+ scl_pd_dis = 1;
-+
-+ dal_write_reg(ptr->ctx, addr, reg2);
-+
-+ if (config_data->type ==
-+ GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
-+ /* should not affect normal I2C R/W */
-+ /* [anaumov] in DAL2, there was
-+ * dc_service_delay_in_microseconds(2500); */
-+ dc_service_sleep_in_milliseconds(ptr->ctx, 3);
-+ }
-+ }
-+
-+ if (aux_pad_mode) {
-+ /* let pins to get de-asserted
-+ * before setting pad to I2C mode */
-+ if (config_data->config.ddc.data_en_bit_present ||
-+ config_data->config.ddc.clock_en_bit_present)
-+ /* [anaumov] in DAL2, there was
-+ * dc_service_delay_in_microseconds(2000); */
-+ dc_service_sleep_in_milliseconds(ptr->ctx, 2);
-+
-+ /* set the I2C pad mode */
-+ /* read the register again,
-+ * some bits may have been changed */
-+ regval = dal_read_reg(ptr->ctx, addr);
-+
-+ set_reg_field_value(
-+ regval,
-+ 0,
-+ DC_GPIO_DDC1_MASK,
-+ AUX_PAD1_MODE);
-+
-+ dal_write_reg(ptr->ctx, addr, regval);
-+ }
-+
-+ return GPIO_RESULT_OK;
-+ case GPIO_DDC_CONFIG_TYPE_MODE_AUX:
-+ /* set the AUX pad mode */
-+ if (!aux_pad_mode) {
-+ set_reg_field_value(
-+ regval,
-+ 1,
-+ DC_GPIO_DDC1_MASK,
-+ AUX_PAD1_MODE);
-+
-+ dal_write_reg(ptr->ctx, addr, regval);
-+ }
-+
-+ return GPIO_RESULT_OK;
-+ case GPIO_DDC_CONFIG_TYPE_POLL_FOR_CONNECT:
-+ if ((hw_gpio->base.en >= GPIO_DDC_LINE_DDC1) &&
-+ (hw_gpio->base.en <= GPIO_DDC_LINE_DDC_VGA)) {
-+ setup_i2c_polling(
-+ ptr->ctx, ADDR_DDC_SETUP, 1, 0);
-+ return GPIO_RESULT_OK;
-+ }
-+ break;
-+ case GPIO_DDC_CONFIG_TYPE_POLL_FOR_DISCONNECT:
-+ if ((hw_gpio->base.en >= GPIO_DDC_LINE_DDC1) &&
-+ (hw_gpio->base.en <= GPIO_DDC_LINE_DDC_VGA)) {
-+ setup_i2c_polling(
-+ ptr->ctx, ADDR_DDC_SETUP, 1, 1);
-+ return GPIO_RESULT_OK;
-+ }
-+ break;
-+ case GPIO_DDC_CONFIG_TYPE_DISABLE_POLLING:
-+ if ((hw_gpio->base.en >= GPIO_DDC_LINE_DDC1) &&
-+ (hw_gpio->base.en <= GPIO_DDC_LINE_DDC_VGA)) {
-+ setup_i2c_polling(
-+ ptr->ctx, ADDR_DDC_SETUP, 0, 0);
-+ return GPIO_RESULT_OK;
-+ }
-+ break;
-+ }
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+}
-+
-+static const struct hw_gpio_pin_funcs funcs = {
-+ .destroy = destroy,
-+ .open = dal_hw_ddc_open,
-+ .get_value = dal_hw_gpio_get_value,
-+ .set_value = dal_hw_gpio_set_value,
-+ .set_config = set_config,
-+ .change_mode = dal_hw_gpio_change_mode,
-+ .close = dal_hw_gpio_close,
-+};
-+
-+
-+static bool construct(
-+ struct hw_ddc_dce110 *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx)
-+{
-+ const struct hw_ddc_dce110_init *init;
-+
-+ if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ if (!dal_hw_ddc_construct(&pin->base, id, en, ctx)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ pin->base.base.base.funcs = &funcs;
-+
-+ switch (id) {
-+ case GPIO_ID_DDC_DATA:
-+ init = hw_ddc_dce110_init_data + en;
-+
-+ pin->base.base.pin_reg = init->hw_gpio_data_reg;
-+ pin->base.mask = init->hw_ddc_mask;
-+ pin->addr = init->hw_ddc_dce110_addr;
-+
-+ return true;
-+ case GPIO_ID_DDC_CLOCK:
-+ init = hw_ddc_dce110_init_clock + en;
-+
-+ pin->base.base.pin_reg = init->hw_gpio_data_reg;
-+ pin->base.mask = init->hw_ddc_mask;
-+ pin->addr = init->hw_ddc_dce110_addr;
-+
-+ return true;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ }
-+
-+ return false;
-+}
-+
-+struct hw_gpio_pin *dal_hw_ddc_dce110_create(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en)
-+{
-+ struct hw_ddc_dce110 *pin = dc_service_alloc(ctx, sizeof(struct hw_ddc_dce110));
-+
-+ if (!pin) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ if (construct(pin, id, en, ctx))
-+ return &pin->base.base.base;
-+
-+ ASSERT_CRITICAL(false);
-+
-+ dc_service_free(ctx, pin);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.h b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.h
-new file mode 100644
-index 0000000..6830369
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.h
-@@ -0,0 +1,46 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_DDC_DCE110_H__
-+#define __DAL_HW_DDC_DCE110_H__
-+
-+struct hw_ddc_dce110_addr {
-+ uint32_t dc_i2c_ddc_setup;
-+};
-+
-+struct hw_ddc_dce110 {
-+ struct hw_ddc base;
-+ struct hw_ddc_dce110_addr addr;
-+};
-+
-+#define DDC_DCE110_FROM_BASE(ddc_base) \
-+ container_of((HW_DDC_FROM_BASE(ddc_base)), struct hw_ddc_dce110, base)
-+
-+struct hw_gpio_pin *dal_hw_ddc_dce110_create(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.c b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.c
-new file mode 100644
-index 0000000..85644c5
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.c
-@@ -0,0 +1,84 @@
-+/*
-+ * Copyright 2013-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "dal_services.h"
-+#include "include/gpio_types.h"
-+#include "../hw_factory.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "../hw_gpio_pin.h"
-+#include "../hw_gpio.h"
-+#include "../hw_ddc.h"
-+#include "../hw_hpd.h"
-+
-+#include "hw_factory_dce110.h"
-+#include "hw_hpd_dce110.h"
-+#include "hw_ddc_dce110.h"
-+
-+/* fucntion table */
-+static const struct hw_factory_funcs funcs = {
-+ .create_dvo = NULL,
-+ .create_ddc_data = dal_hw_ddc_dce110_create,
-+ .create_ddc_clock = dal_hw_ddc_dce110_create,
-+ .create_generic = NULL,
-+ .create_hpd = dal_hw_hpd_dce110_create,
-+ .create_gpio_pad = NULL,
-+ .create_sync = NULL,
-+ .create_gsl = NULL,
-+};
-+
-+/*
-+ * dal_hw_factory_dce110_init
-+ *
-+ * @brief
-+ * Initialize HW factory function pointers and pin info
-+ *
-+ * @param
-+ * struct hw_factory *factory - [out] struct of function pointers
-+ */
-+void dal_hw_factory_dce110_init(struct hw_factory *factory)
-+{
-+ /*TODO check ASIC CAPs*/
-+ factory->number_of_pins[GPIO_ID_DVO1] = 24;
-+ factory->number_of_pins[GPIO_ID_DVO12] = 2;
-+ factory->number_of_pins[GPIO_ID_DVO24] = 1;
-+ factory->number_of_pins[GPIO_ID_DDC_DATA] = 8;
-+ factory->number_of_pins[GPIO_ID_DDC_CLOCK] = 8;
-+ factory->number_of_pins[GPIO_ID_GENERIC] = 7;
-+ factory->number_of_pins[GPIO_ID_HPD] = 6;
-+ factory->number_of_pins[GPIO_ID_GPIO_PAD] = 31;
-+ factory->number_of_pins[GPIO_ID_VIP_PAD] = 0;
-+ factory->number_of_pins[GPIO_ID_SYNC] = 2;
-+ factory->number_of_pins[GPIO_ID_GSL] = 4;
-+
-+ factory->funcs = &funcs;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.h b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.h
-new file mode 100644
-index 0000000..ecf06ed
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.h
-@@ -0,0 +1,32 @@
-+/*
-+ * Copyright 2013-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_FACTORY_DCE110_H__
-+#define __DAL_HW_FACTORY_DCE110_H__
-+
-+/* Initialize HW factory function pointers and pin info */
-+void dal_hw_factory_dce110_init(struct hw_factory *factory);
-+
-+#endif /* __DAL_HW_FACTORY_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.c b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.c
-new file mode 100644
-index 0000000..34405e9
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.c
-@@ -0,0 +1,367 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/gpio_types.h"
-+#include "../hw_gpio_pin.h"
-+#include "../hw_gpio.h"
-+#include "../hw_hpd.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+#include "hw_hpd_dce110.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+/*
-+ * This unit
-+ */
-+
-+static void destruct(
-+ struct hw_hpd_dce110 *pin)
-+{
-+ dal_hw_hpd_destruct(&pin->base);
-+}
-+
-+static void destroy(
-+ struct hw_gpio_pin **ptr)
-+{
-+ struct hw_hpd_dce110 *pin = HPD_DCE110_FROM_BASE(*ptr);
-+
-+ destruct(pin);
-+
-+ dc_service_free((*ptr)->ctx, pin);
-+
-+ *ptr = NULL;
-+}
-+
-+struct hw_gpio_generic_dce110_init {
-+ struct hw_gpio_pin_reg hw_gpio_data_reg;
-+ struct hw_hpd_dce110_addr addr;
-+};
-+
-+static const struct hw_gpio_generic_dce110_init
-+ hw_gpio_generic_dce110_init[GPIO_HPD_COUNT] = {
-+ /* GPIO_HPD_1 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_HPD_MASK,
-+ DC_GPIO_HPD_MASK__DC_GPIO_HPD1_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_A,
-+ DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_EN,
-+ DC_GPIO_HPD_EN__DC_GPIO_HPD1_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_Y,
-+ DC_GPIO_HPD_Y__DC_GPIO_HPD1_Y_MASK
-+ }
-+ },
-+ {
-+ mmHPD0_DC_HPD_INT_STATUS,
-+ mmHPD0_DC_HPD_TOGGLE_FILT_CNTL
-+ }
-+ },
-+ /* GPIO_HPD_2 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_HPD_MASK,
-+ DC_GPIO_HPD_MASK__DC_GPIO_HPD2_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_A,
-+ DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_EN,
-+ DC_GPIO_HPD_EN__DC_GPIO_HPD2_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_Y,
-+ DC_GPIO_HPD_Y__DC_GPIO_HPD2_Y_MASK
-+ }
-+ },
-+ {
-+ mmHPD1_DC_HPD_INT_STATUS,
-+ mmHPD1_DC_HPD_TOGGLE_FILT_CNTL
-+ }
-+ },
-+ /* GPIO_HPD_3 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_HPD_MASK,
-+ DC_GPIO_HPD_MASK__DC_GPIO_HPD3_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_A,
-+ DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_EN,
-+ DC_GPIO_HPD_EN__DC_GPIO_HPD3_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_Y,
-+ DC_GPIO_HPD_Y__DC_GPIO_HPD3_Y_MASK
-+ }
-+ },
-+ {
-+ mmHPD2_DC_HPD_INT_STATUS,
-+ mmHPD2_DC_HPD_TOGGLE_FILT_CNTL
-+ }
-+ },
-+ /* GPIO_HPD_4 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_HPD_MASK,
-+ DC_GPIO_HPD_MASK__DC_GPIO_HPD4_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_A,
-+ DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_EN,
-+ DC_GPIO_HPD_EN__DC_GPIO_HPD4_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_Y,
-+ DC_GPIO_HPD_Y__DC_GPIO_HPD4_Y_MASK
-+ }
-+ },
-+ {
-+ mmHPD3_DC_HPD_INT_STATUS,
-+ mmHPD3_DC_HPD_TOGGLE_FILT_CNTL
-+ }
-+ },
-+ /* GPIO_HPD_5 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_HPD_MASK,
-+ DC_GPIO_HPD_MASK__DC_GPIO_HPD5_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_A,
-+ DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_EN,
-+ DC_GPIO_HPD_EN__DC_GPIO_HPD5_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_Y,
-+ DC_GPIO_HPD_Y__DC_GPIO_HPD5_Y_MASK
-+ }
-+ },
-+ {
-+ mmHPD4_DC_HPD_INT_STATUS,
-+ mmHPD4_DC_HPD_TOGGLE_FILT_CNTL
-+ }
-+ },
-+ /* GPIO_HPD_6 */
-+ {
-+ {
-+ {
-+ mmDC_GPIO_HPD_MASK,
-+ DC_GPIO_HPD_MASK__DC_GPIO_HPD6_MASK_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_A,
-+ DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_EN,
-+ DC_GPIO_HPD_EN__DC_GPIO_HPD6_EN_MASK
-+ },
-+ {
-+ mmDC_GPIO_HPD_Y,
-+ DC_GPIO_HPD_Y__DC_GPIO_HPD6_Y_MASK
-+ }
-+ },
-+ {
-+ mmHPD5_DC_HPD_INT_STATUS,
-+ mmHPD5_DC_HPD_TOGGLE_FILT_CNTL
-+ }
-+ }
-+};
-+
-+static enum gpio_result get_value(
-+ const struct hw_gpio_pin *ptr,
-+ uint32_t *value)
-+{
-+ struct hw_hpd_dce110 *pin = HPD_DCE110_FROM_BASE(ptr);
-+
-+ /* in Interrupt mode we ask for SENSE bit */
-+
-+ if (ptr->mode == GPIO_MODE_INTERRUPT) {
-+ uint32_t regval;
-+ uint32_t hpd_delayed = 0;
-+ uint32_t hpd_sense = 0;
-+
-+ regval = dal_read_reg(
-+ ptr->ctx,
-+ pin->addr.DC_HPD_INT_STATUS);
-+
-+ hpd_delayed = get_reg_field_value(
-+ regval,
-+ DC_HPD_INT_STATUS,
-+ DC_HPD_SENSE_DELAYED);
-+
-+ hpd_sense = get_reg_field_value(
-+ regval,
-+ DC_HPD_INT_STATUS,
-+ DC_HPD_SENSE);
-+
-+ *value = hpd_delayed;
-+ return GPIO_RESULT_OK;
-+ }
-+
-+ /* in any other modes, operate as normal GPIO */
-+
-+ return dal_hw_gpio_get_value(ptr, value);
-+}
-+
-+static enum gpio_result set_config(
-+ struct hw_gpio_pin *ptr,
-+ const struct gpio_config_data *config_data)
-+{
-+ struct hw_hpd_dce110 *pin = HPD_DCE110_FROM_BASE(ptr);
-+
-+ if (!config_data)
-+ return GPIO_RESULT_INVALID_DATA;
-+
-+ {
-+ uint32_t value;
-+
-+ value = dal_read_reg(
-+ ptr->ctx,
-+ pin->addr.DC_HPD_TOGGLE_FILT_CNTL);
-+
-+ set_reg_field_value(
-+ value,
-+ config_data->config.hpd.delay_on_connect / 10,
-+ DC_HPD_TOGGLE_FILT_CNTL,
-+ DC_HPD_CONNECT_INT_DELAY);
-+
-+ set_reg_field_value(
-+ value,
-+ config_data->config.hpd.delay_on_disconnect / 10,
-+ DC_HPD_TOGGLE_FILT_CNTL,
-+ DC_HPD_DISCONNECT_INT_DELAY);
-+
-+ dal_write_reg(
-+ ptr->ctx,
-+ pin->addr.DC_HPD_TOGGLE_FILT_CNTL,
-+ value);
-+
-+ }
-+
-+ return GPIO_RESULT_OK;
-+}
-+
-+static const struct hw_gpio_pin_funcs funcs = {
-+ .destroy = destroy,
-+ .open = dal_hw_gpio_open,
-+ .get_value = get_value,
-+ .set_value = dal_hw_gpio_set_value,
-+ .set_config = set_config,
-+ .change_mode = dal_hw_gpio_change_mode,
-+ .close = dal_hw_gpio_close,
-+};
-+
-+static bool construct(
-+ struct hw_hpd_dce110 *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx)
-+{
-+ const struct hw_gpio_generic_dce110_init *init;
-+
-+ if (id != GPIO_ID_HPD) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ if ((en < GPIO_HPD_MIN) || (en > GPIO_HPD_MAX)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ if (!dal_hw_hpd_construct(&pin->base, id, en, ctx)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ pin->base.base.base.funcs = &funcs;
-+
-+ init = hw_gpio_generic_dce110_init + en;
-+
-+ pin->base.base.pin_reg = init->hw_gpio_data_reg;
-+
-+ pin->addr = init->addr;
-+
-+ return true;
-+}
-+
-+struct hw_gpio_pin *dal_hw_hpd_dce110_create(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en)
-+{
-+ struct hw_hpd_dce110 *pin = dc_service_alloc(ctx, sizeof(struct hw_hpd_dce110));
-+
-+ if (!pin) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ if (construct(pin, id, en, ctx))
-+ return &pin->base.base.base;
-+
-+ ASSERT_CRITICAL(false);
-+
-+ dc_service_free(ctx, pin);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.h b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.h
-new file mode 100644
-index 0000000..d032f4b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.h
-@@ -0,0 +1,47 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_HPD_DCE110_H__
-+#define __DAL_HW_HPD_DCE110_H__
-+
-+struct hw_hpd_dce110_addr {
-+ uint32_t DC_HPD_INT_STATUS;
-+ uint32_t DC_HPD_TOGGLE_FILT_CNTL;
-+};
-+
-+struct hw_hpd_dce110 {
-+ struct hw_hpd base;
-+ struct hw_hpd_dce110_addr addr;
-+};
-+
-+#define HPD_DCE110_FROM_BASE(hpd_base) \
-+ container_of((HW_HPD_FROM_BASE(hpd_base)), struct hw_hpd_dce110, base)
-+
-+struct hw_gpio_pin *dal_hw_hpd_dce110_create(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en);
-+
-+#endif /*__DAL_HW_HPD_DCE110_H__*/
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.c b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.c
-new file mode 100644
-index 0000000..05ac0b2
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.c
-@@ -0,0 +1,440 @@
-+/*
-+ * Copyright 2013-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "dal_services.h"
-+#include "include/gpio_types.h"
-+#include "../hw_translate.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+#include "hw_translate_dce110.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+#include "../hw_gpio_pin.h"
-+#include "../hw_dvo.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+static bool offset_to_id(
-+ uint32_t offset,
-+ uint32_t mask,
-+ enum gpio_id *id,
-+ uint32_t *en)
-+{
-+ switch (offset) {
-+ /* DVO */
-+ case mmDC_GPIO_DVODATA_A:
-+ switch (mask) {
-+ case BUNDLE_A_MASK:
-+ *id = GPIO_ID_DVO12;
-+ *en = GPIO_DVO12_A;
-+ return true;
-+ case BUNDLE_B_MASK:
-+ *id = GPIO_ID_DVO12;
-+ *en = GPIO_DVO12_B;
-+ return true;
-+ case DC_GPIO_DVODATA_A__DC_GPIO_DVODATA_A_MASK:
-+ *id = GPIO_ID_DVO24;
-+ *en = 0;
-+ return true;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+ break;
-+ /* GENERIC */
-+ case mmDC_GPIO_GENERIC_A:
-+ *id = GPIO_ID_GENERIC;
-+ switch (mask) {
-+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
-+ *en = GPIO_GENERIC_A;
-+ return true;
-+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
-+ *en = GPIO_GENERIC_B;
-+ return true;
-+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
-+ *en = GPIO_GENERIC_C;
-+ return true;
-+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
-+ *en = GPIO_GENERIC_D;
-+ return true;
-+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
-+ *en = GPIO_GENERIC_E;
-+ return true;
-+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
-+ *en = GPIO_GENERIC_F;
-+ return true;
-+ case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
-+ *en = GPIO_GENERIC_G;
-+ return true;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+ break;
-+ /* HPD */
-+ case mmDC_GPIO_HPD_A:
-+ *id = GPIO_ID_HPD;
-+ switch (mask) {
-+ case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
-+ *en = GPIO_HPD_1;
-+ return true;
-+ case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
-+ *en = GPIO_HPD_2;
-+ return true;
-+ case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
-+ *en = GPIO_HPD_3;
-+ return true;
-+ case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
-+ *en = GPIO_HPD_4;
-+ return true;
-+ case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
-+ *en = GPIO_HPD_5;
-+ return true;
-+ case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
-+ *en = GPIO_HPD_6;
-+ return true;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+ break;
-+ /* SYNCA */
-+ case mmDC_GPIO_SYNCA_A:
-+ *id = GPIO_ID_SYNC;
-+ switch (mask) {
-+ case DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK:
-+ *en = GPIO_SYNC_HSYNC_A;
-+ return true;
-+ case DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK:
-+ *en = GPIO_SYNC_VSYNC_A;
-+ return true;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+ break;
-+ /* mmDC_GPIO_GENLK_MASK */
-+ case mmDC_GPIO_GENLK_A:
-+ *id = GPIO_ID_GSL;
-+ switch (mask) {
-+ case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
-+ *en = GPIO_GSL_GENLOCK_CLOCK;
-+ return true;
-+ case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
-+ *en = GPIO_GSL_GENLOCK_VSYNC;
-+ return true;
-+ case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
-+ *en = GPIO_GSL_SWAPLOCK_A;
-+ return true;
-+ case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
-+ *en = GPIO_GSL_SWAPLOCK_B;
-+ return true;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+ break;
-+ /* DDC */
-+ /* we don't care about the GPIO_ID for DDC
-+ * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
-+ * directly in the create method */
-+ case mmDC_GPIO_DDC1_A:
-+ *en = GPIO_DDC_LINE_DDC1;
-+ return true;
-+ case mmDC_GPIO_DDC2_A:
-+ *en = GPIO_DDC_LINE_DDC2;
-+ return true;
-+ case mmDC_GPIO_DDC3_A:
-+ *en = GPIO_DDC_LINE_DDC3;
-+ return true;
-+ case mmDC_GPIO_DDC4_A:
-+ *en = GPIO_DDC_LINE_DDC4;
-+ return true;
-+ case mmDC_GPIO_DDC5_A:
-+ *en = GPIO_DDC_LINE_DDC5;
-+ return true;
-+ case mmDC_GPIO_DDC6_A:
-+ *en = GPIO_DDC_LINE_DDC6;
-+ return true;
-+ case mmDC_GPIO_DDCVGA_A:
-+ *en = GPIO_DDC_LINE_DDC_VGA;
-+ return true;
-+ /* GPIO_I2CPAD */
-+ case mmDC_GPIO_I2CPAD_A:
-+ *en = GPIO_DDC_LINE_I2C_PAD;
-+ return true;
-+ /* Not implemented */
-+ case mmDC_GPIO_PWRSEQ_A:
-+ case mmDC_GPIO_PAD_STRENGTH_1:
-+ case mmDC_GPIO_PAD_STRENGTH_2:
-+ case mmDC_GPIO_DEBUG:
-+ return false;
-+ /* UNEXPECTED */
-+ default:
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+}
-+
-+static bool id_to_offset(
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct gpio_pin_info *info)
-+{
-+ bool result = true;
-+
-+ switch (id) {
-+ case GPIO_ID_DVO12:
-+ info->offset = mmDC_GPIO_DVODATA_A;
-+ switch (en) {
-+ case GPIO_DVO12_A:
-+ info->mask = BUNDLE_A_MASK;
-+ break;
-+ case GPIO_DVO12_B:
-+ info->mask = BUNDLE_B_MASK;
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ result = false;
-+ }
-+ break;
-+ case GPIO_ID_DDC_DATA:
-+ info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
-+ switch (en) {
-+ case GPIO_DDC_LINE_DDC1:
-+ info->offset = mmDC_GPIO_DDC1_A;
-+ break;
-+ case GPIO_DDC_LINE_DDC2:
-+ info->offset = mmDC_GPIO_DDC2_A;
-+ break;
-+ case GPIO_DDC_LINE_DDC3:
-+ info->offset = mmDC_GPIO_DDC3_A;
-+ break;
-+ case GPIO_DDC_LINE_DDC4:
-+ info->offset = mmDC_GPIO_DDC4_A;
-+ break;
-+ case GPIO_DDC_LINE_DDC5:
-+ info->offset = mmDC_GPIO_DDC5_A;
-+ break;
-+ case GPIO_DDC_LINE_DDC6:
-+ info->offset = mmDC_GPIO_DDC6_A;
-+ break;
-+ case GPIO_DDC_LINE_DDC_VGA:
-+ info->offset = mmDC_GPIO_DDCVGA_A;
-+ break;
-+ case GPIO_DDC_LINE_I2C_PAD:
-+ info->offset = mmDC_GPIO_I2CPAD_A;
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ result = false;
-+ }
-+ break;
-+ case GPIO_ID_DDC_CLOCK:
-+ info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK;
-+ switch (en) {
-+ case GPIO_DDC_LINE_DDC1:
-+ info->offset = mmDC_GPIO_DDC1_A;
-+ break;
-+ case GPIO_DDC_LINE_DDC2:
-+ info->offset = mmDC_GPIO_DDC2_A;
-+ break;
-+ case GPIO_DDC_LINE_DDC3:
-+ info->offset = mmDC_GPIO_DDC3_A;
-+ break;
-+ case GPIO_DDC_LINE_DDC4:
-+ info->offset = mmDC_GPIO_DDC4_A;
-+ break;
-+ case GPIO_DDC_LINE_DDC5:
-+ info->offset = mmDC_GPIO_DDC5_A;
-+ break;
-+ case GPIO_DDC_LINE_DDC6:
-+ info->offset = mmDC_GPIO_DDC6_A;
-+ break;
-+ case GPIO_DDC_LINE_DDC_VGA:
-+ info->offset = mmDC_GPIO_DDCVGA_A;
-+ break;
-+ case GPIO_DDC_LINE_I2C_PAD:
-+ info->offset = mmDC_GPIO_I2CPAD_A;
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ result = false;
-+ }
-+ break;
-+ case GPIO_ID_GENERIC:
-+ info->offset = mmDC_GPIO_GENERIC_A;
-+ switch (en) {
-+ case GPIO_GENERIC_A:
-+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
-+ break;
-+ case GPIO_GENERIC_B:
-+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
-+ break;
-+ case GPIO_GENERIC_C:
-+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
-+ break;
-+ case GPIO_GENERIC_D:
-+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
-+ break;
-+ case GPIO_GENERIC_E:
-+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
-+ break;
-+ case GPIO_GENERIC_F:
-+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
-+ break;
-+ case GPIO_GENERIC_G:
-+ info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ result = false;
-+ }
-+ break;
-+ case GPIO_ID_HPD:
-+ info->offset = mmDC_GPIO_HPD_A;
-+ switch (en) {
-+ case GPIO_HPD_1:
-+ info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
-+ break;
-+ case GPIO_HPD_2:
-+ info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
-+ break;
-+ case GPIO_HPD_3:
-+ info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
-+ break;
-+ case GPIO_HPD_4:
-+ info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
-+ break;
-+ case GPIO_HPD_5:
-+ info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
-+ break;
-+ case GPIO_HPD_6:
-+ info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ result = false;
-+ }
-+ break;
-+ case GPIO_ID_SYNC:
-+ switch (en) {
-+ case GPIO_SYNC_HSYNC_A:
-+ info->offset = mmDC_GPIO_SYNCA_A;
-+ info->mask = DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK;
-+ break;
-+ case GPIO_SYNC_VSYNC_A:
-+ info->offset = mmDC_GPIO_SYNCA_A;
-+ info->mask = DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK;
-+ break;
-+ case GPIO_SYNC_HSYNC_B:
-+ case GPIO_SYNC_VSYNC_B:
-+ default:
-+ ASSERT_CRITICAL(false);
-+ result = false;
-+ }
-+ break;
-+ case GPIO_ID_GSL:
-+ switch (en) {
-+ case GPIO_GSL_GENLOCK_CLOCK:
-+ info->offset = mmDC_GPIO_GENLK_A;
-+ info->mask = DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK;
-+ break;
-+ case GPIO_GSL_GENLOCK_VSYNC:
-+ info->offset = mmDC_GPIO_GENLK_A;
-+ info->mask =
-+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK;
-+ break;
-+ case GPIO_GSL_SWAPLOCK_A:
-+ info->offset = mmDC_GPIO_GENLK_A;
-+ info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK;
-+ break;
-+ case GPIO_GSL_SWAPLOCK_B:
-+ info->offset = mmDC_GPIO_GENLK_A;
-+ info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK;
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ result = false;
-+ }
-+ break;
-+ case GPIO_ID_DVO24:
-+ info->offset = mmDC_GPIO_DVODATA_A;
-+ info->mask = DC_GPIO_DVODATA_A__DC_GPIO_DVODATA_A_MASK;
-+ break;
-+ case GPIO_ID_DVO1:
-+ case GPIO_ID_VIP_PAD:
-+ default:
-+ ASSERT_CRITICAL(false);
-+ result = false;
-+ }
-+
-+ if (result) {
-+ info->offset_y = info->offset + 2;
-+ info->offset_en = info->offset + 1;
-+ info->offset_mask = info->offset - 1;
-+
-+ info->mask_y = info->mask;
-+ info->mask_en = info->mask;
-+ info->mask_mask = info->mask;
-+ }
-+
-+ return result;
-+}
-+
-+/* function table */
-+static const struct hw_translate_funcs funcs = {
-+ .offset_to_id = offset_to_id,
-+ .id_to_offset = id_to_offset,
-+};
-+
-+/*
-+ * dal_hw_translate_dce110_init
-+ *
-+ * @brief
-+ * Initialize Hw translate function pointers.
-+ *
-+ * @param
-+ * struct hw_translate *tr - [out] struct of function pointers
-+ *
-+ */
-+void dal_hw_translate_dce110_init(struct hw_translate *tr)
-+{
-+ tr->funcs = &funcs;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.h b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.h
-new file mode 100644
-index 0000000..4d16e09
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.h
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright 2013-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_TRANSLATE_DCE110_H__
-+#define __DAL_HW_TRANSLATE_DCE110_H__
-+
-+struct hw_translate;
-+
-+/* Initialize Hw translate function pointers */
-+void dal_hw_translate_dce110_init(struct hw_translate *tr);
-+
-+#endif /* __DAL_HW_TRANSLATE_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/ddc.c b/drivers/gpu/drm/amd/dal/dc/gpio/ddc.c
-new file mode 100644
-index 0000000..548b1cf
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/ddc.c
-@@ -0,0 +1,290 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "include/gpio_interface.h"
-+#include "include/ddc_interface.h"
-+#include "include/gpio_service_interface.h"
-+#include "hw_gpio_pin.h"
-+#include "hw_translate.h"
-+#include "hw_factory.h"
-+#include "gpio_service.h"
-+#include "gpio.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "ddc.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+enum gpio_result dal_ddc_open(
-+ struct ddc *ddc,
-+ enum gpio_mode mode,
-+ enum gpio_ddc_config_type config_type)
-+{
-+ enum gpio_result result;
-+
-+ struct gpio_ddc_open_options data_options;
-+ struct gpio_ddc_open_options clock_options;
-+ struct gpio_config_data config_data;
-+
-+ result = dal_gpio_open_ex(ddc->pin_data, mode, &data_options);
-+
-+ if (result != GPIO_RESULT_OK) {
-+ BREAK_TO_DEBUGGER();
-+ return result;
-+ }
-+
-+ result = dal_gpio_open_ex(ddc->pin_clock, mode, &clock_options);
-+
-+ if (result != GPIO_RESULT_OK) {
-+ BREAK_TO_DEBUGGER();
-+ goto failure;
-+ }
-+
-+ /* DDC clock and data pins should belong
-+ * to the same DDC block id,
-+ * we use the data pin to set the pad mode. */
-+
-+ if (mode == GPIO_MODE_INPUT)
-+ /* this is from detect_sink_type,
-+ * we need extra delay there */
-+ config_data.type = GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE;
-+ else
-+ config_data.type = GPIO_CONFIG_TYPE_DDC;
-+
-+ config_data.config.ddc.type = config_type;
-+ config_data.config.ddc.data_en_bit_present =
-+ data_options.en_bit_present;
-+ config_data.config.ddc.clock_en_bit_present =
-+ clock_options.en_bit_present;
-+
-+ result = dal_gpio_set_config(ddc->pin_data, &config_data);
-+
-+ if (result == GPIO_RESULT_OK)
-+ return result;
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ dal_gpio_close(ddc->pin_clock);
-+
-+failure:
-+ dal_gpio_close(ddc->pin_data);
-+
-+ return result;
-+}
-+
-+enum gpio_result dal_ddc_get_clock(
-+ const struct ddc *ddc,
-+ uint32_t *value)
-+{
-+ return dal_gpio_get_value(ddc->pin_clock, value);
-+}
-+
-+enum gpio_result dal_ddc_set_clock(
-+ const struct ddc *ddc,
-+ uint32_t value)
-+{
-+ return dal_gpio_set_value(ddc->pin_clock, value);
-+}
-+
-+enum gpio_result dal_ddc_get_data(
-+ const struct ddc *ddc,
-+ uint32_t *value)
-+{
-+ return dal_gpio_get_value(ddc->pin_data, value);
-+}
-+
-+enum gpio_result dal_ddc_set_data(
-+ const struct ddc *ddc,
-+ uint32_t value)
-+{
-+ return dal_gpio_set_value(ddc->pin_data, value);
-+}
-+
-+enum gpio_result dal_ddc_change_mode(
-+ struct ddc *ddc,
-+ enum gpio_mode mode)
-+{
-+ enum gpio_result result;
-+
-+ enum gpio_mode original_mode =
-+ dal_gpio_get_mode(ddc->pin_data);
-+
-+ result = dal_gpio_change_mode(ddc->pin_data, mode);
-+
-+ /* [anaumov] DAL2 code returns GPIO_RESULT_NON_SPECIFIC_ERROR
-+ * in case of failures;
-+ * set_mode() is so that, in case of failure,
-+ * we must explicitly set original mode */
-+
-+ if (result != GPIO_RESULT_OK)
-+ goto failure;
-+
-+ result = dal_gpio_change_mode(ddc->pin_clock, mode);
-+
-+ if (result == GPIO_RESULT_OK)
-+ return result;
-+
-+ dal_gpio_change_mode(ddc->pin_clock, original_mode);
-+
-+failure:
-+ dal_gpio_change_mode(ddc->pin_data, original_mode);
-+
-+ return result;
-+}
-+
-+bool dal_ddc_is_hw_supported(
-+ const struct ddc *ddc)
-+{
-+ return ddc->hw_info.hw_supported;
-+}
-+
-+enum gpio_ddc_line dal_ddc_get_line(
-+ const struct ddc *ddc)
-+{
-+ return (enum gpio_ddc_line)dal_gpio_get_enum(ddc->pin_data);
-+}
-+
-+bool dal_ddc_check_line_aborted(
-+ const struct ddc *self)
-+{
-+ /* No arbitration with VBIOS is performed since DCE 6.0 */
-+
-+ return false;
-+}
-+
-+enum gpio_result dal_ddc_set_config(
-+ struct ddc *ddc,
-+ enum gpio_ddc_config_type config_type)
-+{
-+ struct gpio_config_data config_data;
-+
-+ config_data.type = GPIO_CONFIG_TYPE_DDC;
-+
-+ config_data.config.ddc.type = config_type;
-+ config_data.config.ddc.data_en_bit_present = false;
-+ config_data.config.ddc.clock_en_bit_present = false;
-+
-+ return dal_gpio_set_config(ddc->pin_data, &config_data);
-+}
-+
-+void dal_ddc_close(
-+ struct ddc *ddc)
-+{
-+ dal_gpio_close(ddc->pin_clock);
-+ dal_gpio_close(ddc->pin_data);
-+}
-+
-+/*
-+ * @brief
-+ * Creation and destruction
-+ */
-+
-+struct ddc *dal_gpio_create_ddc(
-+ struct gpio_service *service,
-+ uint32_t offset,
-+ uint32_t mask,
-+ struct gpio_ddc_hw_info *info)
-+{
-+ enum gpio_id id;
-+ uint32_t en;
-+ struct ddc *ddc;
-+
-+ if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en))
-+ return NULL;
-+
-+ ddc = dc_service_alloc(service->ctx, sizeof(struct ddc));
-+
-+ if (!ddc) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ ddc->pin_data = dal_gpio_service_create_gpio_ex(
-+ service, GPIO_ID_DDC_DATA, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
-+
-+ if (!ddc->pin_data) {
-+ BREAK_TO_DEBUGGER();
-+ goto failure_1;
-+ }
-+
-+ ddc->pin_clock = dal_gpio_service_create_gpio_ex(
-+ service, GPIO_ID_DDC_CLOCK, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
-+
-+ if (!ddc->pin_clock) {
-+ BREAK_TO_DEBUGGER();
-+ goto failure_2;
-+ }
-+
-+ ddc->hw_info = *info;
-+
-+ ddc->ctx = service->ctx;
-+
-+ return ddc;
-+
-+failure_2:
-+ dal_gpio_service_destroy_gpio(&ddc->pin_data);
-+
-+failure_1:
-+ dc_service_free(service->ctx, ddc);
-+
-+ return NULL;
-+}
-+
-+static void destruct(struct ddc *ddc)
-+{
-+ dal_ddc_close(ddc);
-+ dal_gpio_service_destroy_gpio(&ddc->pin_data);
-+ dal_gpio_service_destroy_gpio(&ddc->pin_clock);
-+
-+}
-+
-+void dal_gpio_destroy_ddc(
-+ struct ddc **ddc)
-+{
-+ if (!ddc || !*ddc) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ destruct(*ddc);
-+ dc_service_free((*ddc)->ctx, *ddc);
-+
-+ *ddc = NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/ddc.h b/drivers/gpu/drm/amd/dal/dc/gpio/ddc.h
-new file mode 100644
-index 0000000..2631571
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/ddc.h
-@@ -0,0 +1,45 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DDC_H__
-+#define __DAL_DDC_H__
-+
-+struct ddc {
-+ struct gpio *pin_data;
-+ struct gpio *pin_clock;
-+ struct gpio_ddc_hw_info hw_info;
-+ struct dc_context *ctx;
-+};
-+
-+struct ddc *dal_gpio_create_ddc(
-+ struct gpio_service *service,
-+ uint32_t offset,
-+ uint32_t mask,
-+ struct gpio_ddc_hw_info *info);
-+
-+void dal_gpio_destroy_ddc(
-+ struct ddc **ddc);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dvo.c b/drivers/gpu/drm/amd/dal/dc/gpio/dvo.c
-new file mode 100644
-index 0000000..a237d25
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dvo.c
-@@ -0,0 +1,138 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/gpio_interface.h"
-+#include "include/dvo_interface.h"
-+#include "include/gpio_service_interface.h"
-+#include "hw_gpio_pin.h"
-+#include "hw_translate.h"
-+#include "hw_factory.h"
-+#include "gpio_service.h"
-+#include "gpio.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "dvo.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+enum gpio_result dal_dvo_open(
-+ struct dvo *dvo,
-+ enum gpio_mode mode)
-+{
-+ return dal_gpio_open(dvo->pin, mode);
-+}
-+
-+enum gpio_result dal_dvo_get_value(
-+ const struct dvo *dvo,
-+ uint32_t *value)
-+{
-+ return dal_gpio_get_value(dvo->pin, value);
-+}
-+
-+enum gpio_result dal_dvo_set_value(
-+ const struct dvo *dvo,
-+ uint32_t value)
-+{
-+ return dal_gpio_set_value(dvo->pin, value);
-+}
-+
-+void dal_dvo_close(
-+ struct dvo *dvo)
-+{
-+ dal_gpio_close(dvo->pin);
-+}
-+
-+/*
-+ * @brief
-+ * Creation and destruction
-+ */
-+
-+struct dvo *dal_dvo_create(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en)
-+{
-+ struct dvo *dvo;
-+
-+ switch (id) {
-+ case GPIO_ID_DVO12:
-+ if ((en < GPIO_DVO12_MIN) || (en > GPIO_DVO12_MAX)) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+ break;
-+ case GPIO_ID_DVO24:
-+ if ((en < GPIO_DVO24_MIN) || (en > GPIO_DVO24_MAX)) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+ break;
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ dvo = dc_service_alloc(service->ctx, sizeof(struct dvo));
-+
-+ if (!dvo) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ dvo->pin = NULL;
-+ dvo->ctx = service->ctx;
-+
-+ return dvo;
-+}
-+
-+void dal_dvo_destroy(
-+ struct dvo **dvo)
-+{
-+ if (!dvo || !*dvo) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ dal_dvo_close(*dvo);
-+
-+ dc_service_free((*dvo)->ctx, *dvo);
-+
-+ *dvo = NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dvo.h b/drivers/gpu/drm/amd/dal/dc/gpio/dvo.h
-new file mode 100644
-index 0000000..0d98b51
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dvo.h
-@@ -0,0 +1,42 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DVO_H__
-+#define __DAL_DVO_H__
-+
-+struct dvo {
-+ struct gpio *pin;
-+ struct dc_context *ctx;
-+};
-+
-+struct dvo *dal_dvo_create(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en);
-+
-+void dal_dvo_destroy(
-+ struct dvo **dvo);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/gpio.h b/drivers/gpu/drm/amd/dal/dc/gpio/gpio.h
-new file mode 100644
-index 0000000..7fcbb69
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/gpio.h
-@@ -0,0 +1,48 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_GPIO_H__
-+#define __DAL_GPIO_H__
-+
-+struct gpio {
-+ struct gpio_service *service;
-+ struct hw_gpio_pin *pin;
-+ enum gpio_id id;
-+ uint32_t en;
-+ enum gpio_mode mode;
-+ /* when GPIO comes from VBIOS, it has defined output state */
-+ enum gpio_pin_output_state output_state;
-+};
-+
-+struct gpio *dal_gpio_create(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en,
-+ enum gpio_pin_output_state output_state);
-+
-+void dal_gpio_destroy(
-+ struct gpio **ptr);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/gpio_base.c b/drivers/gpu/drm/amd/dal/dc/gpio/gpio_base.c
-new file mode 100644
-index 0000000..6115f59
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/gpio_base.c
-@@ -0,0 +1,279 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "include/gpio_interface.h"
-+#include "include/gpio_service_interface.h"
-+#include "hw_gpio_pin.h"
-+#include "hw_translate.h"
-+#include "hw_factory.h"
-+#include "gpio_service.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "gpio.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+/*
-+ * @brief
-+ * Public API
-+ */
-+
-+enum gpio_result dal_gpio_open(
-+ struct gpio *gpio,
-+ enum gpio_mode mode)
-+{
-+ return dal_gpio_open_ex(gpio, mode, NULL);
-+}
-+
-+enum gpio_result dal_gpio_open_ex(
-+ struct gpio *gpio,
-+ enum gpio_mode mode,
-+ void *options)
-+{
-+ if (gpio->pin) {
-+ ASSERT_CRITICAL(false);
-+ return GPIO_RESULT_ALREADY_OPENED;
-+ }
-+
-+ gpio->mode = mode;
-+
-+ return dal_gpio_service_open(
-+ gpio->service, gpio->id, gpio->en, mode, options, &gpio->pin);
-+}
-+
-+enum gpio_result dal_gpio_get_value(
-+ const struct gpio *gpio,
-+ uint32_t *value)
-+{
-+ if (!gpio->pin) {
-+ BREAK_TO_DEBUGGER();
-+ return GPIO_RESULT_NULL_HANDLE;
-+ }
-+
-+ return gpio->pin->funcs->get_value(gpio->pin, value);
-+}
-+
-+enum gpio_result dal_gpio_set_value(
-+ const struct gpio *gpio,
-+ uint32_t value)
-+{
-+ if (!gpio->pin) {
-+ BREAK_TO_DEBUGGER();
-+ return GPIO_RESULT_NULL_HANDLE;
-+ }
-+
-+ return gpio->pin->funcs->set_value(gpio->pin, value);
-+}
-+
-+enum gpio_mode dal_gpio_get_mode(
-+ const struct gpio *gpio)
-+{
-+ return gpio->mode;
-+}
-+
-+enum gpio_result dal_gpio_change_mode(
-+ struct gpio *gpio,
-+ enum gpio_mode mode)
-+{
-+ if (!gpio->pin) {
-+ BREAK_TO_DEBUGGER();
-+ return GPIO_RESULT_NULL_HANDLE;
-+ }
-+
-+ return gpio->pin->funcs->change_mode(gpio->pin, mode);
-+}
-+
-+enum gpio_id dal_gpio_get_id(
-+ const struct gpio *gpio)
-+{
-+ return gpio->id;
-+}
-+
-+uint32_t dal_gpio_get_enum(
-+ const struct gpio *gpio)
-+{
-+ return gpio->en;
-+}
-+
-+enum gpio_result dal_gpio_set_config(
-+ struct gpio *gpio,
-+ const struct gpio_config_data *config_data)
-+{
-+ if (!gpio->pin) {
-+ BREAK_TO_DEBUGGER();
-+ return GPIO_RESULT_NULL_HANDLE;
-+ }
-+
-+ return gpio->pin->funcs->set_config(gpio->pin, config_data);
-+}
-+
-+enum gpio_result dal_gpio_get_pin_info(
-+ const struct gpio *gpio,
-+ struct gpio_pin_info *pin_info)
-+{
-+ return gpio->service->translate.funcs->id_to_offset(
-+ gpio->id, gpio->en, pin_info) ?
-+ GPIO_RESULT_OK : GPIO_RESULT_INVALID_DATA;
-+}
-+
-+enum sync_source dal_gpio_get_sync_source(
-+ const struct gpio *gpio)
-+{
-+ switch (gpio->id) {
-+ case GPIO_ID_GENERIC:
-+ switch (gpio->en) {
-+ case GPIO_GENERIC_A:
-+ return SYNC_SOURCE_IO_GENERIC_A;
-+ case GPIO_GENERIC_B:
-+ return SYNC_SOURCE_IO_GENERIC_B;
-+ case GPIO_GENERIC_C:
-+ return SYNC_SOURCE_IO_GENERIC_C;
-+ case GPIO_GENERIC_D:
-+ return SYNC_SOURCE_IO_GENERIC_D;
-+ case GPIO_GENERIC_E:
-+ return SYNC_SOURCE_IO_GENERIC_E;
-+ case GPIO_GENERIC_F:
-+ return SYNC_SOURCE_IO_GENERIC_F;
-+ default:
-+ return SYNC_SOURCE_NONE;
-+ }
-+ break;
-+ case GPIO_ID_SYNC:
-+ switch (gpio->en) {
-+ case GPIO_SYNC_HSYNC_A:
-+ return SYNC_SOURCE_IO_HSYNC_A;
-+ case GPIO_SYNC_VSYNC_A:
-+ return SYNC_SOURCE_IO_VSYNC_A;
-+ case GPIO_SYNC_HSYNC_B:
-+ return SYNC_SOURCE_IO_HSYNC_B;
-+ case GPIO_SYNC_VSYNC_B:
-+ return SYNC_SOURCE_IO_VSYNC_B;
-+ default:
-+ return SYNC_SOURCE_NONE;
-+ }
-+ break;
-+ case GPIO_ID_HPD:
-+ switch (gpio->en) {
-+ case GPIO_HPD_1:
-+ return SYNC_SOURCE_IO_HPD1;
-+ case GPIO_HPD_2:
-+ return SYNC_SOURCE_IO_HPD2;
-+ default:
-+ return SYNC_SOURCE_NONE;
-+ }
-+ break;
-+ case GPIO_ID_GSL:
-+ switch (gpio->en) {
-+ case GPIO_GSL_GENLOCK_CLOCK:
-+ return SYNC_SOURCE_GSL_IO_GENLOCK_CLOCK;
-+ case GPIO_GSL_GENLOCK_VSYNC:
-+ return SYNC_SOURCE_GSL_IO_GENLOCK_VSYNC;
-+ case GPIO_GSL_SWAPLOCK_A:
-+ return SYNC_SOURCE_GSL_IO_SWAPLOCK_A;
-+ case GPIO_GSL_SWAPLOCK_B:
-+ return SYNC_SOURCE_GSL_IO_SWAPLOCK_B;
-+ default:
-+ return SYNC_SOURCE_NONE;
-+ }
-+ break;
-+ default:
-+ return SYNC_SOURCE_NONE;
-+ }
-+}
-+
-+enum gpio_pin_output_state dal_gpio_get_output_state(
-+ const struct gpio *gpio)
-+{
-+ return gpio->output_state;
-+}
-+
-+void dal_gpio_close(
-+ struct gpio *gpio)
-+{
-+ if (!gpio)
-+ return;
-+
-+ dal_gpio_service_close(gpio->service, &gpio->pin);
-+
-+ gpio->mode = GPIO_MODE_UNKNOWN;
-+}
-+
-+/*
-+ * @brief
-+ * Creation and destruction
-+ */
-+
-+struct gpio *dal_gpio_create(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en,
-+ enum gpio_pin_output_state output_state)
-+{
-+ struct gpio *gpio = dc_service_alloc(service->ctx, sizeof(struct gpio));
-+
-+ if (!gpio) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ gpio->service = service;
-+ gpio->pin = NULL;
-+ gpio->id = id;
-+ gpio->en = en;
-+ gpio->mode = GPIO_MODE_UNKNOWN;
-+ gpio->output_state = output_state;
-+
-+ return gpio;
-+}
-+
-+void dal_gpio_destroy(
-+ struct gpio **gpio)
-+{
-+ if (!gpio || !*gpio) {
-+ ASSERT_CRITICAL(false);
-+ return;
-+ }
-+
-+ dal_gpio_close(*gpio);
-+
-+ dc_service_free((*gpio)->service->ctx, *gpio);
-+
-+ *gpio = NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.c
-new file mode 100644
-index 0000000..08e046b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.c
-@@ -0,0 +1,470 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "dal_services.h"
-+#include "include/gpio_interface.h"
-+#include "include/ddc_interface.h"
-+#include "include/dvo_interface.h"
-+#include "include/irq_interface.h"
-+#include "include/gpio_service_interface.h"
-+#include "hw_translate.h"
-+#include "hw_factory.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "gpio_service.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+#include "hw_gpio_pin.h"
-+#include "gpio.h"
-+#include "dvo.h"
-+#include "ddc.h"
-+#include "irq.h"
-+
-+/*
-+ * This unit
-+ */
-+
-+/*
-+ * @brief
-+ * Public API.
-+ */
-+
-+struct gpio_service *dal_gpio_service_create(
-+ enum dce_version dce_version,
-+ struct dc_context *ctx)
-+{
-+ struct gpio_service *service;
-+
-+ uint32_t index_of_id;
-+
-+ service = dc_service_alloc(ctx, sizeof(struct gpio_service));
-+
-+ if (!service) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ if (!dal_hw_translate_init(&service->translate, dce_version)) {
-+ BREAK_TO_DEBUGGER();
-+ goto failure_1;
-+ }
-+
-+ if (!dal_hw_factory_init(&service->factory, dce_version)) {
-+ BREAK_TO_DEBUGGER();
-+ goto failure_1;
-+ }
-+
-+ /* allocate and initialize business storage */
-+ {
-+ const uint32_t bits_per_uint = sizeof(uint32_t) << 3;
-+
-+ index_of_id = 0;
-+ service->ctx = ctx;
-+
-+ do {
-+ uint32_t number_of_bits =
-+ service->factory.number_of_pins[index_of_id];
-+
-+ uint32_t number_of_uints =
-+ (number_of_bits + bits_per_uint - 1) /
-+ bits_per_uint;
-+
-+ uint32_t *slot;
-+
-+ if (number_of_bits) {
-+ uint32_t index_of_uint = 0;
-+
-+ slot = dc_service_alloc(
-+ ctx,
-+ number_of_uints * sizeof(uint32_t));
-+
-+ if (!slot) {
-+ BREAK_TO_DEBUGGER();
-+ goto failure_2;
-+ }
-+
-+ do {
-+ slot[index_of_uint] = 0;
-+
-+ ++index_of_uint;
-+ } while (index_of_uint < number_of_uints);
-+ } else
-+ slot = NULL;
-+
-+ service->busyness[index_of_id] = slot;
-+
-+ ++index_of_id;
-+ } while (index_of_id < GPIO_ID_COUNT);
-+ }
-+
-+ return service;
-+
-+failure_2:
-+ while (index_of_id) {
-+ uint32_t *slot;
-+
-+ --index_of_id;
-+
-+ slot = service->busyness[index_of_id];
-+
-+ if (slot)
-+ dc_service_free(ctx, slot);
-+ };
-+
-+failure_1:
-+ dc_service_free(ctx, service);
-+
-+ return NULL;
-+}
-+
-+struct gpio *dal_gpio_service_create_gpio(
-+ struct gpio_service *service,
-+ uint32_t offset,
-+ uint32_t mask,
-+ enum gpio_pin_output_state output_state)
-+{
-+ enum gpio_id id;
-+ uint32_t en;
-+
-+ if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ return dal_gpio_create(service, id, en, output_state);
-+}
-+
-+struct gpio *dal_gpio_service_create_gpio_ex(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en,
-+ enum gpio_pin_output_state output_state)
-+{
-+ return dal_gpio_create(service, id, en, output_state);
-+}
-+
-+void dal_gpio_service_destroy_gpio(
-+ struct gpio **gpio)
-+{
-+ dal_gpio_destroy(gpio);
-+}
-+
-+struct ddc *dal_gpio_service_create_ddc(
-+ struct gpio_service *service,
-+ uint32_t offset,
-+ uint32_t mask,
-+ struct gpio_ddc_hw_info *info)
-+{
-+ return dal_gpio_create_ddc(service, offset, mask, info);
-+}
-+
-+void dal_gpio_service_destroy_ddc(
-+ struct ddc **ddc)
-+{
-+ dal_gpio_destroy_ddc(ddc);
-+}
-+
-+struct dvo *dal_gpio_service_create_dvo(
-+ struct gpio_service *service,
-+ uint32_t offset,
-+ uint32_t mask)
-+{
-+ enum gpio_id id;
-+ uint32_t en;
-+
-+ if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ return dal_dvo_create(service, id, en);
-+}
-+
-+struct dvo *dal_gpio_service_create_dvo_ex(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en)
-+{
-+ return dal_dvo_create(service, id, en);
-+}
-+
-+void dal_gpio_service_destroy_dvo(
-+ struct dvo **dvo)
-+{
-+ dal_dvo_destroy(dvo);
-+}
-+
-+struct irq *dal_gpio_service_create_irq(
-+ struct gpio_service *service,
-+ uint32_t offset,
-+ uint32_t mask)
-+{
-+ enum gpio_id id;
-+ uint32_t en;
-+
-+ if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ return dal_gpio_create_irq(service, id, en);
-+}
-+
-+struct irq *dal_gpio_service_create_irq_ex(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en)
-+{
-+ return dal_gpio_create_irq(service, id, en);
-+}
-+
-+void dal_gpio_service_destroy_irq(
-+ struct irq **irq)
-+{
-+ dal_gpio_destroy_irq(irq);
-+}
-+
-+void dal_gpio_service_destroy(
-+ struct gpio_service **ptr)
-+{
-+ if (!ptr || !*ptr) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ /* free business storage */
-+ {
-+ uint32_t index_of_id = 0;
-+
-+ do {
-+ uint32_t *slot = (*ptr)->busyness[index_of_id];
-+
-+ if (slot)
-+ dc_service_free((*ptr)->ctx, slot);
-+
-+ ++index_of_id;
-+ } while (index_of_id < GPIO_ID_COUNT);
-+ }
-+
-+ dc_service_free((*ptr)->ctx, *ptr);
-+
-+ *ptr = NULL;
-+}
-+
-+/*
-+ * @brief
-+ * Private API.
-+ */
-+
-+static bool is_pin_busy(
-+ const struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en)
-+{
-+ const uint32_t bits_per_uint = sizeof(uint32_t) << 3;
-+
-+ const uint32_t *slot = service->busyness[id] + (en / bits_per_uint);
-+
-+ return 0 != (*slot & (1 << (en % bits_per_uint)));
-+}
-+
-+static bool is_some_pin_busy(
-+ const struct gpio_service *service,
-+ enum gpio_id id)
-+{
-+ const uint32_t bits_per_uint = sizeof(uint32_t) << 3;
-+
-+ uint32_t index_of_uint = 0;
-+
-+ uint32_t number_of_uints =
-+ service->factory.number_of_pins[id];
-+
-+ number_of_uints = (number_of_uints + bits_per_uint - 1) / bits_per_uint;
-+
-+ while (index_of_uint < number_of_uints) {
-+ if (service->busyness[id][index_of_uint])
-+ return true;
-+
-+ ++index_of_uint;
-+ };
-+
-+ return false;
-+}
-+
-+static void set_pin_busy(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en)
-+{
-+ const uint32_t bits_per_uint = sizeof(uint32_t) << 3;
-+
-+ service->busyness[id][en / bits_per_uint] |=
-+ (1 << (en % bits_per_uint));
-+}
-+
-+static void set_pin_free(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en)
-+{
-+ const uint32_t bits_per_uint = sizeof(uint32_t) << 3;
-+
-+ service->busyness[id][en / bits_per_uint] &=
-+ ~(1 << (en % bits_per_uint));
-+}
-+
-+enum gpio_result dal_gpio_service_open(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en,
-+ enum gpio_mode mode,
-+ void *options,
-+ struct hw_gpio_pin **ptr)
-+{
-+ struct hw_gpio_pin *pin;
-+
-+ if (!service->busyness[id]) {
-+ ASSERT_CRITICAL(false);
-+ return GPIO_RESULT_OPEN_FAILED;
-+ }
-+
-+ if (is_pin_busy(service, id, en)) {
-+ ASSERT_CRITICAL(false);
-+ return GPIO_RESULT_DEVICE_BUSY;
-+ }
-+
-+ switch (id) {
-+ case GPIO_ID_DVO1:
-+ /* [anaumov] not implemented, commented with "to do" */
-+ ASSERT_CRITICAL(false);
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+ case GPIO_ID_DVO12:
-+ if (!service->busyness[GPIO_ID_DVO24]) {
-+ ASSERT_CRITICAL(false);
-+ return GPIO_RESULT_OPEN_FAILED;
-+ }
-+
-+ if (is_some_pin_busy(service, GPIO_ID_DVO24)) {
-+ ASSERT_CRITICAL(false);
-+ return GPIO_RESULT_DEVICE_BUSY;
-+ }
-+
-+ pin = service->factory.funcs->create_dvo(
-+ service->ctx, id, en);
-+ break;
-+ case GPIO_ID_DVO24:
-+ if (!service->busyness[GPIO_ID_DVO12]) {
-+ ASSERT_CRITICAL(false);
-+ return GPIO_RESULT_OPEN_FAILED;
-+ }
-+
-+ if (is_some_pin_busy(service, GPIO_ID_DVO12)) {
-+ ASSERT_CRITICAL(false);
-+ return GPIO_RESULT_DEVICE_BUSY;
-+ }
-+
-+ pin = service->factory.funcs->create_dvo(
-+ service->ctx, id, en);
-+ break;
-+ case GPIO_ID_DDC_DATA:
-+ pin = service->factory.funcs->create_ddc_data(
-+ service->ctx, id, en);
-+ break;
-+ case GPIO_ID_DDC_CLOCK:
-+ pin = service->factory.funcs->create_ddc_clock(
-+ service->ctx, id, en);
-+ break;
-+ case GPIO_ID_GENERIC:
-+ pin = service->factory.funcs->create_generic(
-+ service->ctx, id, en);
-+ break;
-+ case GPIO_ID_HPD:
-+ pin = service->factory.funcs->create_hpd(
-+ service->ctx, id, en);
-+ break;
-+ case GPIO_ID_GPIO_PAD:
-+ pin = service->factory.funcs->create_gpio_pad(
-+ service->ctx, id, en);
-+ break;
-+ case GPIO_ID_SYNC:
-+ pin = service->factory.funcs->create_sync(
-+ service->ctx, id, en);
-+ break;
-+ case GPIO_ID_GSL:
-+ pin = service->factory.funcs->create_gsl(
-+ service->ctx, id, en);
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+ }
-+
-+ if (!pin) {
-+ ASSERT_CRITICAL(false);
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+ }
-+
-+ if (!pin->funcs->open(pin, mode, options)) {
-+ ASSERT_CRITICAL(false);
-+ dal_gpio_service_close(service, &pin);
-+ return GPIO_RESULT_OPEN_FAILED;
-+ }
-+
-+ set_pin_busy(service, id, en);
-+ *ptr = pin;
-+ return GPIO_RESULT_OK;
-+}
-+
-+void dal_gpio_service_close(
-+ struct gpio_service *service,
-+ struct hw_gpio_pin **ptr)
-+{
-+ struct hw_gpio_pin *pin;
-+
-+ if (!ptr) {
-+ ASSERT_CRITICAL(false);
-+ return;
-+ }
-+
-+ pin = *ptr;
-+
-+ if (pin) {
-+ set_pin_free(service, pin->id, pin->en);
-+
-+ pin->funcs->close(pin);
-+
-+ pin->funcs->destroy(ptr);
-+ }
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.h b/drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.h
-new file mode 100644
-index 0000000..a17c438
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.h
-@@ -0,0 +1,57 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_GPIO_SERVICE_H__
-+#define __DAL_GPIO_SERVICE_H__
-+
-+struct hw_translate;
-+struct hw_factory;
-+
-+struct gpio_service {
-+ struct dc_context *ctx;
-+ struct hw_translate translate;
-+ struct hw_factory factory;
-+ /*
-+ * @brief
-+ * Business storage.
-+ * For each member of 'enum gpio_id',
-+ * store array of bits (packed into uint32_t slots),
-+ * index individual bit by 'en' value */
-+ uint32_t *busyness[GPIO_ID_COUNT];
-+};
-+
-+enum gpio_result dal_gpio_service_open(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en,
-+ enum gpio_mode mode,
-+ void *options,
-+ struct hw_gpio_pin **ptr);
-+
-+void dal_gpio_service_close(
-+ struct gpio_service *service,
-+ struct hw_gpio_pin **ptr);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c b/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c
-new file mode 100644
-index 0000000..0608f16
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c
-@@ -0,0 +1,105 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/gpio_types.h"
-+#include "hw_gpio_pin.h"
-+#include "hw_gpio.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "hw_ddc.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+#define FROM_HW_GPIO(ptr) \
-+ container_of((ptr), struct hw_ddc, base)
-+
-+#define FROM_HW_GPIO_PIN(ptr) \
-+ FROM_HW_GPIO(container_of((ptr), struct hw_gpio, base))
-+
-+bool dal_hw_ddc_open(
-+ struct hw_gpio_pin *ptr,
-+ enum gpio_mode mode,
-+ void *options)
-+{
-+ struct hw_ddc *pin = FROM_HW_GPIO_PIN(ptr);
-+
-+ uint32_t en;
-+
-+ if (!options) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ /* get the EN bit before overwriting it */
-+
-+ dal_hw_gpio_get_reg_value(
-+ ptr->ctx,
-+ &pin->base.pin_reg.DC_GPIO_DATA_EN,
-+ &en);
-+
-+ ((struct gpio_ddc_open_options *)options)->en_bit_present = (en != 0);
-+
-+ return dal_hw_gpio_open(ptr, mode, options);
-+}
-+
-+bool dal_hw_ddc_construct(
-+ struct hw_ddc *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx)
-+{
-+ if (!dal_hw_gpio_construct(&pin->base, id, en, ctx))
-+ return false;
-+
-+ pin->mask.DC_GPIO_DDC_MASK_MASK = 0;
-+ pin->mask.DC_GPIO_DDC_PD_EN_MASK = 0;
-+ pin->mask.DC_GPIO_DDC_RECV_MASK = 0;
-+ pin->mask.AUX_PAD_MODE_MASK = 0;
-+ pin->mask.AUX_POL_MASK = 0;
-+ pin->mask.DC_GPIO_DDCCLK_STR_MASK = 0;
-+
-+ return true;
-+}
-+
-+void dal_hw_ddc_destruct(
-+ struct hw_ddc *pin)
-+{
-+ dal_hw_gpio_destruct(&pin->base);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.h b/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.h
-new file mode 100644
-index 0000000..a3a727c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.h
-@@ -0,0 +1,60 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_DDC_H__
-+#define __DAL_HW_DDC_H__
-+
-+struct hw_ddc_mask {
-+ uint32_t DC_GPIO_DDC_MASK_MASK;
-+ uint32_t DC_GPIO_DDC_PD_EN_MASK;
-+ uint32_t DC_GPIO_DDC_RECV_MASK;
-+ uint32_t AUX_PAD_MODE_MASK;
-+ uint32_t AUX_POL_MASK;
-+ uint32_t DC_GPIO_DDCCLK_STR_MASK;
-+};
-+
-+struct hw_ddc {
-+ struct hw_gpio base;
-+ struct hw_ddc_mask mask;
-+};
-+
-+#define HW_DDC_FROM_BASE(hw_gpio) \
-+ container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_ddc, base)
-+
-+bool dal_hw_ddc_construct(
-+ struct hw_ddc *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx);
-+
-+void dal_hw_ddc_destruct(
-+ struct hw_ddc *pin);
-+
-+bool dal_hw_ddc_open(
-+ struct hw_gpio_pin *ptr,
-+ enum gpio_mode mode,
-+ void *options);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_dvo.c b/drivers/gpu/drm/amd/dal/dc/gpio/hw_dvo.c
-new file mode 100644
-index 0000000..a5a07f0
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_dvo.c
-@@ -0,0 +1,318 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/gpio_types.h"
-+#include "hw_gpio_pin.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "hw_dvo.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+#define FROM_HW_GPIO_PIN(ptr) \
-+ container_of((ptr), struct hw_dvo, base)
-+
-+static void store_dvo_registers(
-+ struct hw_dvo *pin)
-+{
-+ pin->store.dvo_mask = dal_read_reg(
-+ pin->base.ctx, pin->addr.DC_GPIO_DVODATA_MASK);
-+ pin->store.dvo_en = dal_read_reg(
-+ pin->base.ctx, pin->addr.DC_GPIO_DVODATA_EN);
-+ pin->store.dvo_data_a = dal_read_reg(
-+ pin->base.ctx, pin->addr.DC_GPIO_DVODATA_A);
-+}
-+
-+static void restore_dvo_registers(
-+ struct hw_dvo *pin)
-+{
-+ {
-+ const uint32_t addr = pin->addr.DC_GPIO_DVODATA_MASK;
-+
-+ uint32_t data = dal_read_reg(pin->base.ctx, addr);
-+
-+ data &= ~pin->dvo_mask;
-+ data |= pin->store.dvo_mask & pin->dvo_mask;
-+
-+ dal_write_reg(pin->base.ctx, addr, data);
-+ }
-+
-+ {
-+ const uint32_t addr = pin->addr.DC_GPIO_DVODATA_EN;
-+
-+ uint32_t data = dal_read_reg(pin->base.ctx, addr);
-+
-+ data &= ~pin->dvo_mask;
-+ data |= pin->store.dvo_en & pin->dvo_mask;
-+
-+ dal_write_reg(pin->base.ctx, addr, data);
-+ }
-+
-+ {
-+ const uint32_t addr = pin->addr.DC_GPIO_DVODATA_A;
-+
-+ uint32_t data = dal_read_reg(pin->base.ctx, addr);
-+
-+ data &= ~pin->dvo_mask;
-+ data |= pin->store.dvo_data_a & pin->dvo_mask;
-+
-+ dal_write_reg(pin->base.ctx, addr, data);
-+ }
-+}
-+
-+static void program_dvo(
-+ struct hw_dvo *pin,
-+ bool output)
-+{
-+ /* Turn on Mask bits for the requested channel,
-+ * this will enable the channel for software control. */
-+ {
-+ const uint32_t addr = pin->addr.DC_GPIO_DVODATA_MASK;
-+
-+ uint32_t mask = dal_read_reg(pin->base.ctx, addr);
-+
-+ uint32_t data = pin->dvo_mask | mask;
-+
-+ dal_write_reg(pin->base.ctx, addr, data);
-+ }
-+
-+ /* Turn off/on the Enable bits on the requested channel,
-+ * this will set it to Input/Output mode. */
-+ {
-+ const uint32_t addr = pin->addr.DC_GPIO_DVODATA_EN;
-+
-+ uint32_t enable = dal_read_reg(pin->base.ctx, addr);
-+
-+ uint32_t data = output ?
-+ (pin->dvo_mask | enable) :
-+ (~pin->dvo_mask & enable);
-+
-+ dal_write_reg(pin->base.ctx, addr, data);
-+ }
-+}
-+
-+static void program_dvo_strength(
-+ struct hw_dvo *pin)
-+{
-+ const uint32_t addr = pin->addr.DVO_STRENGTH_CONTROL;
-+
-+ uint32_t data = dal_read_reg(pin->base.ctx, addr);
-+
-+ data &= ~pin->dvo_strength_mask;
-+ data |= pin->dvo_strength & pin->dvo_strength_mask;
-+
-+ dal_write_reg(pin->base.ctx, addr, data);
-+}
-+
-+static void disable_on_chip_terminators(
-+ struct hw_dvo *pin)
-+{
-+ const uint32_t addr = pin->addr.D1CRTC_MVP_CONTROL1;
-+
-+ uint32_t data = dal_read_reg(pin->base.ctx, addr);
-+
-+ pin->store.mvp_terminator_state = (data & pin->mvp_termination_mask);
-+
-+ data &= ~pin->mvp_termination_mask;
-+
-+ dal_write_reg(pin->base.ctx, addr, data);
-+}
-+
-+static void restore_on_chip_terminators(
-+ struct hw_dvo *pin)
-+{
-+ const uint32_t addr = pin->addr.D1CRTC_MVP_CONTROL1;
-+
-+ uint32_t data = dal_read_reg(pin->base.ctx, addr);
-+
-+ data &= ~pin->mvp_termination_mask;
-+
-+ if (pin->store.mvp_terminator_state)
-+ data |= pin->mvp_termination_mask;
-+
-+ dal_write_reg(pin->base.ctx, addr, data);
-+}
-+
-+bool dal_hw_dvo_open(
-+ struct hw_gpio_pin *ptr,
-+ enum gpio_mode mode,
-+ void *options)
-+{
-+ struct hw_dvo *pin = FROM_HW_GPIO_PIN(ptr);
-+
-+ store_dvo_registers(pin);
-+
-+ ptr->mode = mode;
-+
-+ switch (mode) {
-+ case GPIO_MODE_INPUT:
-+ program_dvo_strength(pin);
-+ disable_on_chip_terminators(pin);
-+ program_dvo(pin, false);
-+
-+ ptr->opened = true;
-+ break;
-+ case GPIO_MODE_OUTPUT:
-+ program_dvo_strength(pin);
-+ disable_on_chip_terminators(pin);
-+ program_dvo(pin, true);
-+
-+ ptr->opened = true;
-+ break;
-+ default:
-+ /* unsupported mode */
-+ BREAK_TO_DEBUGGER();
-+
-+ ptr->opened = false;
-+ }
-+
-+ return ptr->opened;
-+}
-+
-+enum gpio_result dal_hw_dvo_get_value(
-+ const struct hw_gpio_pin *ptr,
-+ uint32_t *value)
-+{
-+ const struct hw_dvo *pin = FROM_HW_GPIO_PIN(ptr);
-+
-+ if (ptr->mode != GPIO_MODE_INPUT)
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+
-+ *value = dal_read_reg(ptr->ctx, pin->addr.DC_GPIO_DVODATA_Y);
-+
-+ *value &= pin->dvo_mask;
-+ *value >>= pin->dvo_shift;
-+
-+ return GPIO_RESULT_OK;
-+}
-+
-+enum gpio_result dal_hw_dvo_set_value(
-+ const struct hw_gpio_pin *ptr,
-+ uint32_t value)
-+{
-+ const struct hw_dvo *pin = FROM_HW_GPIO_PIN(ptr);
-+
-+ uint32_t masked_value;
-+
-+ if (ptr->mode != GPIO_MODE_OUTPUT) {
-+ BREAK_TO_DEBUGGER();
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+ }
-+
-+ /* Ensure there is no overflow of the value written.
-+ * Value cannot be more than 12 bits for a 12-bit channel. */
-+
-+ masked_value = value << pin->dvo_shift;
-+
-+ if (masked_value != (masked_value & pin->dvo_mask)) {
-+ BREAK_TO_DEBUGGER();
-+ return GPIO_RESULT_INVALID_DATA;
-+ }
-+
-+ masked_value &= pin->dvo_mask;
-+
-+ /* read the DataA register
-+ * mask off the Bundle that we want to write to
-+ * or the data into the register */
-+ {
-+ const uint32_t addr = pin->addr.DC_GPIO_DVODATA_A;
-+
-+ uint32_t data = dal_read_reg(ptr->ctx, addr);
-+
-+ data &= ~pin->dvo_mask;
-+ data |= masked_value;
-+
-+ dal_write_reg(ptr->ctx, addr, data);
-+ }
-+
-+ return GPIO_RESULT_OK;
-+}
-+
-+void dal_hw_dvo_close(
-+ struct hw_gpio_pin *ptr)
-+{
-+ struct hw_dvo *pin = FROM_HW_GPIO_PIN(ptr);
-+
-+ restore_dvo_registers(pin);
-+ restore_on_chip_terminators(pin);
-+
-+ ptr->mode = GPIO_MODE_UNKNOWN;
-+
-+ ptr->opened = false;
-+}
-+
-+bool dal_hw_dvo_construct(
-+ struct hw_dvo *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx)
-+{
-+ struct hw_gpio_pin *base = &pin->base;
-+
-+ if (!dal_hw_gpio_pin_construct(base, id, en, ctx))
-+ return false;
-+
-+ pin->addr.DC_GPIO_DVODATA_MASK = 0;
-+ pin->addr.DC_GPIO_DVODATA_EN = 0;
-+ pin->addr.DC_GPIO_DVODATA_A = 0;
-+ pin->addr.DC_GPIO_DVODATA_Y = 0;
-+ pin->addr.DVO_STRENGTH_CONTROL = 0;
-+ pin->addr.D1CRTC_MVP_CONTROL1 = 0;
-+
-+ pin->dvo_mask = 0;
-+ pin->dvo_shift = 0;
-+ pin->dvo_strength_mask = 0;
-+ pin->mvp_termination_mask = 0;
-+
-+ pin->dvo_strength = 0;
-+
-+ pin->store.dvo_mask = 0;
-+ pin->store.dvo_en = 0;
-+ pin->store.dvo_data_a = 0;
-+ pin->store.mvp_terminator_state = false;
-+
-+ return true;
-+}
-+
-+void dal_hw_dvo_destruct(
-+ struct hw_dvo *pin)
-+{
-+ dal_hw_gpio_pin_destruct(&pin->base);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_dvo.h b/drivers/gpu/drm/amd/dal/dc/gpio/hw_dvo.h
-new file mode 100644
-index 0000000..5a120c2
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_dvo.h
-@@ -0,0 +1,89 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_DVO_H__
-+#define __DAL_HW_DVO_H__
-+
-+#define BUNDLE_A_SHIFT 12L
-+#define BUNDLE_B_SHIFT 0L
-+
-+struct hw_dvo {
-+ struct hw_gpio_pin base;
-+ /* Register indices are represented by member variables,
-+ * are to be filled in by derived classes.
-+ * These members permit the use of common code
-+ * for programming registers where the sequence is the same
-+ * but the register sets are different */
-+ struct {
-+ uint32_t DC_GPIO_DVODATA_MASK;
-+ uint32_t DC_GPIO_DVODATA_EN;
-+ uint32_t DC_GPIO_DVODATA_A;
-+ uint32_t DC_GPIO_DVODATA_Y;
-+ uint32_t DVO_STRENGTH_CONTROL;
-+ uint32_t D1CRTC_MVP_CONTROL1;
-+ } addr;
-+
-+ /* Mask and shift differentiates between Bundle A and Bundle B */
-+ uint32_t dvo_mask;
-+ uint32_t dvo_shift;
-+ uint32_t dvo_strength_mask;
-+ uint32_t mvp_termination_mask;
-+
-+ uint32_t dvo_strength;
-+
-+ struct {
-+ uint32_t dvo_mask;
-+ uint32_t dvo_en;
-+ uint32_t dvo_data_a;
-+ bool mvp_terminator_state;
-+ } store;
-+};
-+
-+bool dal_hw_dvo_construct(
-+ struct hw_dvo *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx);
-+
-+void dal_hw_dvo_destruct(
-+ struct hw_dvo *pin);
-+
-+bool dal_hw_dvo_open(
-+ struct hw_gpio_pin *ptr,
-+ enum gpio_mode mode,
-+ void *options);
-+
-+enum gpio_result dal_hw_dvo_get_value(
-+ const struct hw_gpio_pin *ptr,
-+ uint32_t *value);
-+
-+enum gpio_result dal_hw_dvo_set_value(
-+ const struct hw_gpio_pin *ptr,
-+ uint32_t value);
-+
-+void dal_hw_dvo_close(
-+ struct hw_gpio_pin *ptr);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c b/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c
-new file mode 100644
-index 0000000..d1b6b7e
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c
-@@ -0,0 +1,80 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/gpio_types.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "hw_factory.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+#include "dce110/hw_factory_dce110.h"
-+#endif
-+/*
-+ * This unit
-+ */
-+
-+bool dal_hw_factory_init(
-+ struct hw_factory *factory,
-+ enum dce_version dce_version)
-+{
-+ switch (dce_version) {
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ case DCE_VERSION_11_0:
-+ dal_hw_factory_dce110_init(factory);
-+ return true;
-+#endif
-+ default:
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+}
-+
-+void dal_hw_factory_destroy(
-+ struct dc_context *ctx,
-+ struct hw_factory **factory)
-+{
-+ if (!factory || !*factory) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ dc_service_free(ctx, *factory);
-+
-+ *factory = NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.h b/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.h
-new file mode 100644
-index 0000000..f16678c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.h
-@@ -0,0 +1,74 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_FACTORY_H__
-+#define __DAL_HW_FACTORY_H__
-+
-+struct hw_gpio_pin;
-+
-+struct hw_factory {
-+ uint32_t number_of_pins[GPIO_ID_COUNT];
-+
-+ const struct hw_factory_funcs {
-+ struct hw_gpio_pin *(*create_dvo)(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en);
-+ struct hw_gpio_pin *(*create_ddc_data)(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en);
-+ struct hw_gpio_pin *(*create_ddc_clock)(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en);
-+ struct hw_gpio_pin *(*create_generic)(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en);
-+ struct hw_gpio_pin *(*create_hpd)(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en);
-+ struct hw_gpio_pin *(*create_gpio_pad)(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en);
-+ struct hw_gpio_pin *(*create_sync)(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en);
-+ struct hw_gpio_pin *(*create_gsl)(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en);
-+ } *funcs;
-+};
-+
-+bool dal_hw_factory_init(
-+ struct hw_factory *factory,
-+ enum dce_version dce_version);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.c b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.c
-new file mode 100644
-index 0000000..2964d5d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.c
-@@ -0,0 +1,408 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/gpio_types.h"
-+#include "hw_gpio_pin.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "hw_gpio.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+enum gpio_result dal_hw_gpio_get_reg_value(
-+ struct dc_context *ctx,
-+ const struct addr_mask *reg,
-+ uint32_t *value)
-+{
-+ *value = dal_read_reg(ctx, reg->addr);
-+
-+ *value &= reg->mask;
-+
-+ return GPIO_RESULT_OK;
-+}
-+
-+enum gpio_result dal_hw_gpio_set_reg_value(
-+ struct dc_context *ctx,
-+ const struct addr_mask *reg,
-+ uint32_t value)
-+{
-+ uint32_t prev_value;
-+
-+ if ((value & reg->mask) != value) {
-+ BREAK_TO_DEBUGGER();
-+ return GPIO_RESULT_INVALID_DATA;
-+ }
-+
-+ prev_value = dal_read_reg(ctx, reg->addr);
-+
-+ prev_value &= ~reg->mask;
-+ prev_value |= (value & reg->mask);
-+
-+ dal_write_reg(ctx, reg->addr, prev_value);
-+
-+ return GPIO_RESULT_OK;
-+}
-+
-+uint32_t dal_hw_gpio_get_shift_from_mask(
-+ uint32_t mask)
-+{
-+ uint32_t result = 0;
-+
-+ if (!mask)
-+ return 32;
-+
-+ do {
-+ if ((1 << result) & mask)
-+ break;
-+
-+ ++result;
-+ } while (result < 32);
-+
-+ return result;
-+}
-+
-+#define FROM_HW_GPIO_PIN(ptr) \
-+ container_of((ptr), struct hw_gpio, base)
-+
-+static void store_registers(
-+ struct hw_gpio *pin)
-+{
-+ dal_hw_gpio_get_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_MASK,
-+ &pin->store.mask);
-+ dal_hw_gpio_get_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_A,
-+ &pin->store.a);
-+ dal_hw_gpio_get_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_EN,
-+ &pin->store.en);
-+
-+ if (pin->mux_supported)
-+ dal_hw_gpio_get_reg_value(
-+ pin->base.ctx,
-+ &pin->mux_reg.GPIO_MUX_CONTROL,
-+ &pin->store.mux);
-+}
-+
-+static void restore_registers(
-+ struct hw_gpio *pin)
-+{
-+ dal_hw_gpio_set_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_MASK,
-+ pin->store.mask);
-+ dal_hw_gpio_set_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_A,
-+ pin->store.a);
-+ dal_hw_gpio_set_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_EN,
-+ pin->store.en);
-+
-+ if (pin->mux_supported)
-+ dal_hw_gpio_set_reg_value(
-+ pin->base.ctx,
-+ &pin->mux_reg.GPIO_MUX_CONTROL,
-+ pin->store.mux);
-+}
-+
-+bool dal_hw_gpio_open(
-+ struct hw_gpio_pin *ptr,
-+ enum gpio_mode mode,
-+ void *options)
-+{
-+ struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
-+
-+ store_registers(pin);
-+
-+ ptr->opened = (pin->funcs->config_mode(pin, mode) == GPIO_RESULT_OK);
-+
-+ return ptr->opened;
-+}
-+
-+enum gpio_result dal_hw_gpio_get_value(
-+ const struct hw_gpio_pin *ptr,
-+ uint32_t *value)
-+{
-+ const struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
-+
-+ enum gpio_result result;
-+
-+ switch (ptr->mode) {
-+ case GPIO_MODE_INPUT:
-+ case GPIO_MODE_OUTPUT:
-+ case GPIO_MODE_HARDWARE:
-+ case GPIO_MODE_FAST_OUTPUT:
-+ result = dal_hw_gpio_get_reg_value(
-+ ptr->ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_Y,
-+ value);
-+ /* Clients does not know that the value
-+ * comes from register and is shifted. */
-+ if (result == GPIO_RESULT_OK)
-+ *value >>= dal_hw_gpio_get_shift_from_mask(
-+ pin->pin_reg.DC_GPIO_DATA_Y.mask);
-+ break;
-+ default:
-+ result = GPIO_RESULT_NON_SPECIFIC_ERROR;
-+ }
-+
-+ return result;
-+}
-+
-+enum gpio_result dal_hw_gpio_set_value(
-+ const struct hw_gpio_pin *ptr,
-+ uint32_t value)
-+{
-+ struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
-+
-+ /* This is the public interface
-+ * where the input comes from client, not shifted yet
-+ * (because client does not know the shifts). */
-+
-+ switch (ptr->mode) {
-+ case GPIO_MODE_OUTPUT:
-+ return dal_hw_gpio_set_reg_value(
-+ ptr->ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_A,
-+ value << dal_hw_gpio_get_shift_from_mask(
-+ pin->pin_reg.DC_GPIO_DATA_A.mask));
-+ case GPIO_MODE_FAST_OUTPUT:
-+ /* We use (EN) to faster switch (used in DDC GPIO).
-+ * So (A) is grounded, output is driven by (EN = 0)
-+ * to pull the line down (output == 0) and (EN=1)
-+ * then output is tri-state */
-+ return dal_hw_gpio_set_reg_value(
-+ ptr->ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_EN,
-+ pin->pin_reg.DC_GPIO_DATA_EN.mask &
-+ ~(value << dal_hw_gpio_get_shift_from_mask(
-+ pin->pin_reg.DC_GPIO_DATA_EN.mask)));
-+ default:
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+ }
-+}
-+
-+enum gpio_result dal_hw_gpio_change_mode(
-+ struct hw_gpio_pin *ptr,
-+ enum gpio_mode mode)
-+{
-+ struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
-+
-+ return pin->funcs->config_mode(pin, mode);
-+}
-+
-+void dal_hw_gpio_close(
-+ struct hw_gpio_pin *ptr)
-+{
-+ struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
-+
-+ restore_registers(pin);
-+
-+ ptr->mode = GPIO_MODE_UNKNOWN;
-+ ptr->opened = false;
-+}
-+
-+static enum gpio_result config_mode_input(
-+ struct hw_gpio *pin)
-+{
-+ enum gpio_result result;
-+
-+ /* turn off output enable, act as input pin;
-+ * program the pin as GPIO, mask out signal driven by HW */
-+
-+ result = dal_hw_gpio_set_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_EN,
-+ 0);
-+
-+ if (result != GPIO_RESULT_OK)
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+
-+ result = dal_hw_gpio_set_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_MASK,
-+ pin->pin_reg.DC_GPIO_DATA_MASK.mask);
-+
-+ if (result != GPIO_RESULT_OK)
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+
-+ return GPIO_RESULT_OK;
-+}
-+
-+static enum gpio_result config_mode_output(
-+ struct hw_gpio *pin)
-+{
-+ enum gpio_result result;
-+
-+ /* turn on output enable, act as output pin;
-+ * program the pin as GPIO, mask out signal driven by HW */
-+
-+ result = dal_hw_gpio_set_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_EN,
-+ pin->pin_reg.DC_GPIO_DATA_EN.mask);
-+
-+ if (result != GPIO_RESULT_OK)
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+
-+ result = dal_hw_gpio_set_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_MASK,
-+ pin->pin_reg.DC_GPIO_DATA_MASK.mask);
-+
-+ if (result != GPIO_RESULT_OK)
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+
-+ return GPIO_RESULT_OK;
-+}
-+
-+static enum gpio_result config_mode_fast_output(
-+ struct hw_gpio *pin)
-+{
-+ enum gpio_result result;
-+
-+ /* grounding the A register then use the EN register bit
-+ * will have faster effect on the rise time */
-+
-+ result = dal_hw_gpio_set_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_A, 0);
-+
-+ if (result != GPIO_RESULT_OK)
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+
-+ result = dal_hw_gpio_set_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_MASK,
-+ pin->pin_reg.DC_GPIO_DATA_MASK.mask);
-+
-+ if (result != GPIO_RESULT_OK)
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+
-+ return GPIO_RESULT_OK;
-+}
-+
-+static enum gpio_result config_mode_hardware(
-+ struct hw_gpio *pin)
-+{
-+ /* program the pin as tri-state, pin is driven by HW */
-+
-+ enum gpio_result result =
-+ dal_hw_gpio_set_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_MASK,
-+ 0);
-+
-+ if (result != GPIO_RESULT_OK)
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+
-+ return GPIO_RESULT_OK;
-+}
-+
-+enum gpio_result dal_hw_gpio_config_mode(
-+ struct hw_gpio *pin,
-+ enum gpio_mode mode)
-+{
-+ pin->base.mode = mode;
-+
-+ switch (mode) {
-+ case GPIO_MODE_INPUT:
-+ return config_mode_input(pin);
-+ case GPIO_MODE_OUTPUT:
-+ return config_mode_output(pin);
-+ case GPIO_MODE_FAST_OUTPUT:
-+ return config_mode_fast_output(pin);
-+ case GPIO_MODE_HARDWARE:
-+ return config_mode_hardware(pin);
-+ default:
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+ }
-+}
-+
-+const struct hw_gpio_funcs func = {
-+ .config_mode = dal_hw_gpio_config_mode,
-+};
-+
-+bool dal_hw_gpio_construct(
-+ struct hw_gpio *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx)
-+{
-+ struct hw_gpio_pin *base = &pin->base;
-+
-+ if (!dal_hw_gpio_pin_construct(base, id, en, ctx))
-+ return false;
-+
-+ pin->funcs = &func;
-+
-+ pin->pin_reg.DC_GPIO_DATA_MASK.addr = 0;
-+ pin->pin_reg.DC_GPIO_DATA_MASK.mask = 0;
-+ pin->pin_reg.DC_GPIO_DATA_A.addr = 0;
-+ pin->pin_reg.DC_GPIO_DATA_A.mask = 0;
-+ pin->pin_reg.DC_GPIO_DATA_EN.addr = 0;
-+ pin->pin_reg.DC_GPIO_DATA_EN.mask = 0;
-+ pin->pin_reg.DC_GPIO_DATA_Y.addr = 0;
-+ pin->pin_reg.DC_GPIO_DATA_Y.mask = 0;
-+ pin->mux_reg.GPIO_MUX_CONTROL.addr = 0;
-+ pin->mux_reg.GPIO_MUX_CONTROL.mask = 0;
-+ pin->mux_reg.GPIO_MUX_STEREO_SEL.addr = 0;
-+ pin->mux_reg.GPIO_MUX_STEREO_SEL.mask = 0;
-+
-+ pin->store.mask = 0;
-+ pin->store.a = 0;
-+ pin->store.en = 0;
-+ pin->store.mux = 0;
-+
-+ pin->mux_supported = false;
-+
-+ return true;
-+}
-+
-+void dal_hw_gpio_destruct(
-+ struct hw_gpio *pin)
-+{
-+ dal_hw_gpio_pin_destruct(&pin->base);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.h b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.h
-new file mode 100644
-index 0000000..44eb86e
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.h
-@@ -0,0 +1,129 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_GPIO_H__
-+#define __DAL_HW_GPIO_H__
-+
-+struct addr_mask {
-+ uint32_t addr;
-+ uint32_t mask;
-+};
-+
-+enum gpio_result dal_hw_gpio_get_reg_value(
-+ struct dc_context *ctx,
-+ const struct addr_mask *reg,
-+ uint32_t *value);
-+
-+enum gpio_result dal_hw_gpio_set_reg_value(
-+ struct dc_context *ctx,
-+ const struct addr_mask *reg,
-+ uint32_t value);
-+
-+uint32_t dal_hw_gpio_get_shift_from_mask(
-+ uint32_t mask);
-+
-+struct hw_gpio;
-+
-+struct hw_gpio_funcs {
-+ enum gpio_result (*config_mode)(
-+ struct hw_gpio *pin,
-+ enum gpio_mode mode);
-+};
-+
-+/* Register indices are represented by member variables
-+ * and are to be filled in by constructors of derived classes.
-+ * These members permit the use of common code
-+ * for programming registers, where the sequence is the same
-+ * but register sets are different.
-+ * Some GPIOs have HW mux which allows to choose
-+ * what is the source of the signal in HW mode */
-+
-+struct hw_gpio_pin_reg {
-+ struct addr_mask DC_GPIO_DATA_MASK;
-+ struct addr_mask DC_GPIO_DATA_A;
-+ struct addr_mask DC_GPIO_DATA_EN;
-+ struct addr_mask DC_GPIO_DATA_Y;
-+};
-+
-+struct hw_gpio_mux_reg {
-+ struct addr_mask GPIO_MUX_CONTROL;
-+ struct addr_mask GPIO_MUX_STEREO_SEL;
-+};
-+
-+struct hw_gpio {
-+ struct hw_gpio_pin base;
-+ const struct hw_gpio_funcs *funcs;
-+ struct hw_gpio_pin_reg pin_reg;
-+ struct hw_gpio_mux_reg mux_reg;
-+
-+ /* variables to save register value */
-+ struct {
-+ uint32_t mask;
-+ uint32_t a;
-+ uint32_t en;
-+ uint32_t mux;
-+ } store;
-+
-+ /* GPIO MUX support */
-+ bool mux_supported;
-+};
-+
-+#define HW_GPIO_FROM_BASE(hw_gpio_pin) \
-+ container_of((hw_gpio_pin), struct hw_gpio, base)
-+
-+bool dal_hw_gpio_construct(
-+ struct hw_gpio *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx);
-+
-+bool dal_hw_gpio_open(
-+ struct hw_gpio_pin *pin,
-+ enum gpio_mode mode,
-+ void *options);
-+
-+enum gpio_result dal_hw_gpio_get_value(
-+ const struct hw_gpio_pin *pin,
-+ uint32_t *value);
-+
-+enum gpio_result dal_hw_gpio_config_mode(
-+ struct hw_gpio *pin,
-+ enum gpio_mode mode);
-+
-+void dal_hw_gpio_destruct(
-+ struct hw_gpio *pin);
-+
-+enum gpio_result dal_hw_gpio_set_value(
-+ const struct hw_gpio_pin *ptr,
-+ uint32_t value);
-+
-+enum gpio_result dal_hw_gpio_change_mode(
-+ struct hw_gpio_pin *ptr,
-+ enum gpio_mode mode);
-+
-+void dal_hw_gpio_close(
-+ struct hw_gpio_pin *ptr);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.c b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.c
-new file mode 100644
-index 0000000..057c439
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.c
-@@ -0,0 +1,93 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/gpio_types.h"
-+#include "hw_gpio_pin.h"
-+#include "hw_gpio.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "hw_gpio_pad.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+#define FROM_HW_GPIO(ptr) \
-+ container_of((ptr), struct hw_gpio_pad, base)
-+
-+#define FROM_HW_GPIO_PIN(ptr) \
-+ FROM_HW_GPIO(container_of((ptr), struct hw_gpio, base))
-+
-+enum gpio_result dal_hw_gpio_pad_get_value(
-+ const struct hw_gpio_pin *ptr,
-+ uint32_t *value)
-+{
-+ const struct hw_gpio_pad *pin = FROM_HW_GPIO_PIN(ptr);
-+
-+ if (ptr->mode == GPIO_MODE_INTERRUPT)
-+ /* in Interrupt mode, ask for interrupt status bit */
-+ return dal_hw_gpio_get_reg_value(
-+ ptr->ctx,
-+ &pin->gpiopad_int_status,
-+ value);
-+ else
-+ /* for any mode other than Interrupt,
-+ * gpio_pad operates as normal GPIO */
-+ return dal_hw_gpio_get_value(ptr, value);
-+}
-+
-+bool dal_hw_gpio_pad_construct(
-+ struct hw_gpio_pad *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx)
-+{
-+ if (!dal_hw_gpio_construct(&pin->base, id, en, ctx))
-+ return false;
-+
-+ pin->gpiopad_int_status.addr = 0;
-+ pin->gpiopad_int_status.mask = 0;
-+
-+ return true;
-+}
-+
-+void dal_hw_gpio_pad_destruct(
-+ struct hw_gpio_pad *pin)
-+{
-+ dal_hw_gpio_destruct(&pin->base);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.h b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.h
-new file mode 100644
-index 0000000..34b470a
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.h
-@@ -0,0 +1,47 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_GPIO_PAD_H__
-+#define __DAL_HW_GPIO_PAD_H__
-+
-+struct hw_gpio_pad {
-+ struct hw_gpio base;
-+ struct addr_mask gpiopad_int_status;
-+};
-+
-+bool dal_hw_gpio_pad_construct(
-+ struct hw_gpio_pad *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx);
-+
-+void dal_hw_gpio_pad_destruct(
-+ struct hw_gpio_pad *pin);
-+
-+enum gpio_result dal_hw_gpio_pad_get_value(
-+ const struct hw_gpio_pin *ptr,
-+ uint32_t *value);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.c b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.c
-new file mode 100644
-index 0000000..4ab1848
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.c
-@@ -0,0 +1,86 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/gpio_types.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "hw_gpio_pin.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+enum gpio_result dal_hw_gpio_pin_set_config(
-+ struct hw_gpio_pin *pin,
-+ const struct gpio_config_data *config_data)
-+{
-+ /* Attention!
-+ * You must override this method in derived class */
-+
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+}
-+
-+enum gpio_result dal_hw_gpio_pin_change_mode(
-+ struct hw_gpio_pin *pin,
-+ enum gpio_mode mode)
-+{
-+ /* Attention!
-+ * You must override this method in derived class */
-+
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+}
-+
-+bool dal_hw_gpio_pin_construct(
-+ struct hw_gpio_pin *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx)
-+{
-+ pin->ctx = ctx;
-+ pin->id = id;
-+ pin->en = en;
-+ pin->mode = GPIO_MODE_UNKNOWN;
-+ pin->opened = false;
-+
-+ return true;
-+}
-+
-+void dal_hw_gpio_pin_destruct(
-+ struct hw_gpio_pin *pin)
-+{
-+ ASSERT(!pin->opened);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.h b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.h
-new file mode 100644
-index 0000000..d1f2f27
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.h
-@@ -0,0 +1,79 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_GPIO_PIN_H__
-+#define __DAL_HW_GPIO_PIN_H__
-+
-+struct hw_gpio_pin;
-+
-+struct hw_gpio_pin_funcs {
-+ void (*destroy)(
-+ struct hw_gpio_pin **ptr);
-+ bool (*open)(
-+ struct hw_gpio_pin *pin,
-+ enum gpio_mode mode,
-+ void *options);
-+ enum gpio_result (*get_value)(
-+ const struct hw_gpio_pin *pin,
-+ uint32_t *value);
-+ enum gpio_result (*set_value)(
-+ const struct hw_gpio_pin *pin,
-+ uint32_t value);
-+ enum gpio_result (*set_config)(
-+ struct hw_gpio_pin *pin,
-+ const struct gpio_config_data *config_data);
-+ enum gpio_result (*change_mode)(
-+ struct hw_gpio_pin *pin,
-+ enum gpio_mode mode);
-+ void (*close)(
-+ struct hw_gpio_pin *pin);
-+};
-+
-+struct hw_gpio_pin {
-+ const struct hw_gpio_pin_funcs *funcs;
-+ enum gpio_id id;
-+ uint32_t en;
-+ enum gpio_mode mode;
-+ bool opened;
-+ struct dc_context *ctx;
-+};
-+
-+bool dal_hw_gpio_pin_construct(
-+ struct hw_gpio_pin *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx);
-+
-+void dal_hw_gpio_pin_destruct(
-+ struct hw_gpio_pin *pin);
-+
-+enum gpio_result dal_hw_gpio_pin_change_mode(
-+ struct hw_gpio_pin *pin,
-+ enum gpio_mode mode);
-+
-+enum gpio_result dal_hw_gpio_pin_set_config(
-+ struct hw_gpio_pin *pin,
-+ const struct gpio_config_data *config_data);
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.c b/drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.c
-new file mode 100644
-index 0000000..c09d74c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.c
-@@ -0,0 +1,88 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/gpio_types.h"
-+#include "hw_gpio_pin.h"
-+#include "hw_gpio.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "hw_hpd.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+static enum gpio_result config_mode(
-+ struct hw_gpio *pin,
-+ enum gpio_mode mode)
-+{
-+ if (mode == GPIO_MODE_INTERRUPT) {
-+ /* Interrupt mode supported only by HPD (IrqGpio) pins. */
-+ pin->base.mode = mode;
-+
-+ return dal_hw_gpio_set_reg_value(
-+ pin->base.ctx,
-+ &pin->pin_reg.DC_GPIO_DATA_MASK,
-+ 0);
-+ } else
-+ /* For any mode other than Interrupt,
-+ * act as normal GPIO. */
-+ return dal_hw_gpio_config_mode(pin, mode);
-+}
-+
-+const struct hw_gpio_funcs hw_hpd_func = {
-+ .config_mode = config_mode,
-+};
-+
-+bool dal_hw_hpd_construct(
-+ struct hw_hpd *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx)
-+{
-+ if (!dal_hw_gpio_construct(&pin->base, id, en, ctx))
-+ return false;
-+ pin->base.funcs = &hw_hpd_func;
-+ return true;
-+}
-+
-+void dal_hw_hpd_destruct(
-+ struct hw_hpd *pin)
-+{
-+ dal_hw_gpio_destruct(&pin->base);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.h b/drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.h
-new file mode 100644
-index 0000000..3fb82df
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.h
-@@ -0,0 +1,45 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_HPD_H__
-+#define __DAL_HW_HPD_H__
-+
-+struct hw_hpd {
-+ struct hw_gpio base;
-+};
-+
-+#define HW_HPD_FROM_BASE(hw_gpio) \
-+ container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_hpd, base)
-+
-+bool dal_hw_hpd_construct(
-+ struct hw_hpd *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx);
-+
-+void dal_hw_hpd_destruct(
-+ struct hw_hpd *pin);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c
-new file mode 100644
-index 0000000..96e135f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c
-@@ -0,0 +1,67 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/gpio_types.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "hw_translate.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+#include "dce110/hw_translate_dce110.h"
-+#endif
-+
-+/*
-+ * This unit
-+ */
-+
-+bool dal_hw_translate_init(
-+ struct hw_translate *translate,
-+ enum dce_version dce_version)
-+{
-+ switch (dce_version) {
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ case DCE_VERSION_11_0:
-+ dal_hw_translate_dce110_init(translate);
-+ return true;
-+#endif
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.h b/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.h
-new file mode 100644
-index 0000000..d5740ac
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.h
-@@ -0,0 +1,49 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_TRANSLATE_H__
-+#define __DAL_HW_TRANSLATE_H__
-+
-+struct hw_translate_funcs {
-+ bool (*offset_to_id)(
-+ uint32_t offset,
-+ uint32_t mask,
-+ enum gpio_id *id,
-+ uint32_t *en);
-+ bool (*id_to_offset)(
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct gpio_pin_info *info);
-+};
-+
-+struct hw_translate {
-+ const struct hw_translate_funcs *funcs;
-+};
-+
-+bool dal_hw_translate_init(
-+ struct hw_translate *translate,
-+ enum dce_version dce_version);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/irq.c b/drivers/gpu/drm/amd/dal/dc/gpio/irq.c
-new file mode 100644
-index 0000000..382b89f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/irq.c
-@@ -0,0 +1,181 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/gpio_interface.h"
-+#include "include/irq_interface.h"
-+#include "include/gpio_service_interface.h"
-+#include "hw_gpio_pin.h"
-+#include "hw_translate.h"
-+#include "hw_factory.h"
-+#include "gpio_service.h"
-+#include "gpio.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "irq.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+enum gpio_result dal_irq_open(
-+ struct irq *irq)
-+{
-+ return dal_gpio_open(irq->pin, GPIO_MODE_INTERRUPT);
-+}
-+
-+enum gpio_result dal_irq_get_value(
-+ const struct irq *irq,
-+ uint32_t *value)
-+{
-+ return dal_gpio_get_value(irq->pin, value);
-+}
-+
-+enum dc_irq_source dal_irq_get_source(
-+ const struct irq *irq)
-+{
-+ enum gpio_id id = dal_gpio_get_id(irq->pin);
-+
-+ switch (id) {
-+ case GPIO_ID_HPD:
-+ return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1 +
-+ dal_gpio_get_enum(irq->pin));
-+ case GPIO_ID_GPIO_PAD:
-+ return (enum dc_irq_source)(DC_IRQ_SOURCE_GPIOPAD0 +
-+ dal_gpio_get_enum(irq->pin));
-+ default:
-+ return DC_IRQ_SOURCE_INVALID;
-+ }
-+}
-+
-+enum dc_irq_source dal_irq_get_rx_source(
-+ const struct irq *irq)
-+{
-+ enum gpio_id id = dal_gpio_get_id(irq->pin);
-+
-+ switch (id) {
-+ case GPIO_ID_HPD:
-+ return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1RX +
-+ dal_gpio_get_enum(irq->pin));
-+ default:
-+ return DC_IRQ_SOURCE_INVALID;
-+ }
-+}
-+
-+enum gpio_result dal_irq_setup_hpd_filter(
-+ struct irq *irq,
-+ struct gpio_hpd_config *config)
-+{
-+ struct gpio_config_data config_data;
-+
-+ if (!config)
-+ return GPIO_RESULT_INVALID_DATA;
-+
-+ config_data.type = GPIO_CONFIG_TYPE_HPD;
-+ config_data.config.hpd = *config;
-+
-+ return dal_gpio_set_config(irq->pin, &config_data);
-+}
-+
-+void dal_irq_close(
-+ struct irq *irq)
-+{
-+ dal_gpio_close(irq->pin);
-+}
-+
-+/*
-+ * @brief
-+ * Creation and destruction
-+ */
-+
-+struct irq *dal_gpio_create_irq(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en)
-+{
-+ struct irq *irq;
-+
-+ switch (id) {
-+ case GPIO_ID_HPD:
-+ case GPIO_ID_GPIO_PAD:
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ irq = dc_service_alloc(service->ctx, sizeof(struct irq));
-+
-+ if (!irq) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ irq->pin = dal_gpio_service_create_gpio_ex(
-+ service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
-+ irq->ctx = service->ctx;
-+
-+ if (irq->pin)
-+ return irq;
-+
-+ ASSERT_CRITICAL(false);
-+
-+ dc_service_free(service->ctx, irq);
-+
-+ return NULL;
-+}
-+
-+static void destruct(struct irq *irq)
-+{
-+ dal_irq_close(irq);
-+ dal_gpio_service_destroy_gpio(&irq->pin);
-+
-+}
-+
-+void dal_gpio_destroy_irq(
-+ struct irq **irq)
-+{
-+ if (!irq || !*irq) {
-+ ASSERT_CRITICAL(false);
-+ return;
-+ }
-+
-+ destruct(*irq);
-+ dc_service_free((*irq)->ctx, *irq);
-+
-+ *irq = NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/irq.h b/drivers/gpu/drm/amd/dal/dc/gpio/irq.h
-new file mode 100644
-index 0000000..b69375c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/irq.h
-@@ -0,0 +1,42 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_IRQ_H__
-+#define __DAL_IRQ_H__
-+
-+struct irq {
-+ struct gpio *pin;
-+ struct dc_context *ctx;
-+};
-+
-+struct irq *dal_gpio_create_irq(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en);
-+
-+void dal_gpio_destroy_irq(
-+ struct irq **ptr);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/Makefile b/drivers/gpu/drm/amd/dal/dc/gpu/Makefile
-new file mode 100644
-index 0000000..d3d6faf
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/Makefile
-@@ -0,0 +1,26 @@
-+#
-+# Makefile for the 'gpu' sub-component of DAL.
-+# It provides the control and status of HW adapter resources,
-+# that are global for the ASIC and sharable between pipes.
-+
-+GPU = calc_pll_clock_source.o clock_source.o \
-+dc_clock_generator.o display_clock.o divider_range.o \
-+ext_clock_source.o pll_clock_source.o
-+
-+AMD_DAL_GPU = $(addprefix $(AMDDALPATH)/dc/gpu/,$(GPU))
-+
-+AMD_DAL_FILES += $(AMD_DAL_GPU)
-+
-+
-+###############################################################################
-+# DCE 110 family
-+###############################################################################
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_0
-+GPU_DCE110 = display_clock_dce110.o \
-+ pll_clock_source_dce110.o ext_clock_source_dce110.o \
-+ vce_clock_source_dce110.o dc_clock_gating_dce110.o
-+
-+AMD_DAL_GPU_DCE110 = $(addprefix $(AMDDALPATH)/dc/gpu/dce110/,$(GPU_DCE110))
-+
-+AMD_DAL_FILES += $(AMD_DAL_GPU_DCE110)
-+endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/calc_pll_clock_source.c b/drivers/gpu/drm/amd/dal/dc/gpu/calc_pll_clock_source.c
-new file mode 100644
-index 0000000..7c94733
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/calc_pll_clock_source.c
-@@ -0,0 +1,407 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "calc_pll_clock_source.h"
-+#include "include/bios_parser_interface.h"
-+#include "include/logger_interface.h"
-+
-+/**
-+* Function: calculate_fb_and_fractional_fb_divider
-+*
-+* * DESCRIPTION: Calculates feedback and fractional feedback dividers values
-+*
-+*PARAMETERS:
-+* targetPixelClock Desired frequency in 10 KHz
-+* ref_divider Reference divider (already known)
-+* postDivider Post Divider (already known)
-+* feedback_divider_param Pointer where to store
-+* calculated feedback divider value
-+* fract_feedback_divider_param Pointer where to store
-+* calculated fract feedback divider value
-+*
-+*RETURNS:
-+* It fills the locations pointed by feedback_divider_param
-+* and fract_feedback_divider_param
-+* It returns - true if feedback divider not 0
-+* - false should never happen)
-+*/
-+static bool calculate_fb_and_fractional_fb_divider(
-+ struct calc_pll_clock_source *calc_pll_cs,
-+ uint32_t target_pix_clk_khz,
-+ uint32_t ref_divider,
-+ uint32_t post_divider,
-+ uint32_t *feedback_divider_param,
-+ uint32_t *fract_feedback_divider_param)
-+{
-+ uint64_t feedback_divider;
-+
-+ feedback_divider =
-+ (uint64_t)(target_pix_clk_khz * ref_divider * post_divider);
-+ feedback_divider *= 10;
-+ /* additional factor, since we divide by 10 afterwards */
-+ feedback_divider *= (uint64_t)(calc_pll_cs->fract_fb_divider_factor);
-+ feedback_divider = div_u64(feedback_divider, calc_pll_cs->ref_freq_khz);
-+
-+/*Round to the number of precision
-+ * The following code replace the old code (ullfeedbackDivider + 5)/10
-+ * for example if the difference between the number
-+ * of fractional feedback decimal point and the fractional FB Divider precision
-+ * is 2 then the equation becomes (ullfeedbackDivider + 5*100) / (10*100))*/
-+
-+ feedback_divider += (uint64_t)
-+ (5 * calc_pll_cs->fract_fb_divider_precision_factor);
-+ feedback_divider =
-+ div_u64(feedback_divider,
-+ calc_pll_cs->fract_fb_divider_precision_factor * 10);
-+ feedback_divider *= (uint64_t)
-+ (calc_pll_cs->fract_fb_divider_precision_factor);
-+
-+ *feedback_divider_param =
-+ div_u64_rem(
-+ feedback_divider,
-+ calc_pll_cs->fract_fb_divider_factor,
-+ fract_feedback_divider_param);
-+
-+ if (*feedback_divider_param != 0)
-+ return true;
-+ return false;
-+}
-+
-+/**
-+*calc_fb_divider_checking_tolerance
-+*
-+*DESCRIPTION: Calculates Feedback and Fractional Feedback divider values
-+* for passed Reference and Post divider, checking for tolerance.
-+*PARAMETERS:
-+* pll_settings Pointer to structure
-+* ref_divider Reference divider (already known)
-+* postDivider Post Divider (already known)
-+* tolerance Tolerance for Calculated Pixel Clock to be within
-+*
-+*RETURNS:
-+* It fills the PLLSettings structure with PLL Dividers values
-+* if calculated values are within required tolerance
-+* It returns - true if eror is within tolerance
-+* - false if eror is not within tolerance
-+*/
-+static bool calc_fb_divider_checking_tolerance(
-+ struct calc_pll_clock_source *calc_pll_cs,
-+ struct pll_settings *pll_settings,
-+ uint32_t ref_divider,
-+ uint32_t post_divider,
-+ uint32_t tolerance)
-+{
-+ uint32_t feedback_divider;
-+ uint32_t fract_feedback_divider;
-+ uint32_t actual_calculated_clock_khz;
-+ uint32_t abs_err;
-+ uint64_t actual_calc_clk_khz;
-+
-+ calculate_fb_and_fractional_fb_divider(
-+ calc_pll_cs,
-+ pll_settings->adjusted_pix_clk,
-+ ref_divider,
-+ post_divider,
-+ &feedback_divider,
-+ &fract_feedback_divider);
-+
-+ /*Actual calculated value*/
-+ actual_calc_clk_khz = (uint64_t)(feedback_divider *
-+ calc_pll_cs->fract_fb_divider_factor) +
-+ fract_feedback_divider;
-+ actual_calc_clk_khz *= calc_pll_cs->ref_freq_khz;
-+ actual_calc_clk_khz =
-+ div_u64(actual_calc_clk_khz,
-+ ref_divider * post_divider *
-+ calc_pll_cs->fract_fb_divider_factor);
-+
-+ actual_calculated_clock_khz = (uint32_t)(actual_calc_clk_khz);
-+
-+ abs_err = (actual_calculated_clock_khz >
-+ pll_settings->adjusted_pix_clk)
-+ ? actual_calculated_clock_khz -
-+ pll_settings->adjusted_pix_clk
-+ : pll_settings->adjusted_pix_clk -
-+ actual_calculated_clock_khz;
-+
-+ if (abs_err <= tolerance) {
-+ /*found good values*/
-+ pll_settings->reference_freq = calc_pll_cs->ref_freq_khz;
-+ pll_settings->reference_divider = ref_divider;
-+ pll_settings->feedback_divider = feedback_divider;
-+ pll_settings->fract_feedback_divider = fract_feedback_divider;
-+ pll_settings->pix_clk_post_divider = post_divider;
-+ pll_settings->calculated_pix_clk =
-+ actual_calculated_clock_khz;
-+ pll_settings->vco_freq =
-+ actual_calculated_clock_khz * post_divider;
-+ return true;
-+ }
-+ return false;
-+}
-+
-+static bool calc_pll_dividers_in_range(
-+ struct calc_pll_clock_source *calc_pll_cs,
-+ struct pll_settings *pll_settings,
-+ uint32_t min_ref_divider,
-+ uint32_t max_ref_divider,
-+ uint32_t min_post_divider,
-+ uint32_t max_post_divider,
-+ uint32_t err_tolerance)
-+{
-+ uint32_t ref_divider;
-+ uint32_t post_divider;
-+ uint32_t tolerance;
-+
-+/* This is err_tolerance / 10000 = 0.0025 - acceptable error of 0.25%
-+ * This is errorTolerance / 10000 = 0.0001 - acceptable error of 0.01%*/
-+ tolerance = (pll_settings->adjusted_pix_clk * err_tolerance) /
-+ 10000;
-+ if (tolerance < CALC_PLL_CLK_SRC_ERR_TOLERANCE)
-+ tolerance = CALC_PLL_CLK_SRC_ERR_TOLERANCE;
-+
-+ for (
-+ post_divider = max_post_divider;
-+ post_divider >= min_post_divider;
-+ --post_divider) {
-+ for (
-+ ref_divider = min_ref_divider;
-+ ref_divider <= max_ref_divider;
-+ ++ref_divider) {
-+ if (calc_fb_divider_checking_tolerance(
-+ calc_pll_cs,
-+ pll_settings,
-+ ref_divider,
-+ post_divider,
-+ tolerance)) {
-+ return true;
-+ }
-+ }
-+ }
-+
-+ return false;
-+}
-+
-+uint32_t dal_clock_source_calculate_pixel_clock_pll_dividers(
-+ struct calc_pll_clock_source *calc_pll_cs,
-+ struct pll_settings *pll_settings)
-+{
-+ uint32_t err_tolerance;
-+ uint32_t min_post_divider;
-+ uint32_t max_post_divider;
-+ uint32_t min_ref_divider;
-+ uint32_t max_ref_divider;
-+
-+ if (pll_settings->adjusted_pix_clk == 0) {
-+ dal_logger_write(calc_pll_cs->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s Bad requested pixel clock", __func__);
-+ return MAX_PLL_CALC_ERROR;
-+ }
-+
-+/* 1) Find Post divider ranges */
-+ if (pll_settings->pix_clk_post_divider) {
-+ min_post_divider = pll_settings->pix_clk_post_divider;
-+ max_post_divider = pll_settings->pix_clk_post_divider;
-+ } else {
-+ min_post_divider = calc_pll_cs->min_pix_clock_pll_post_divider;
-+ if (min_post_divider * pll_settings->adjusted_pix_clk <
-+ calc_pll_cs->min_vco_khz) {
-+ min_post_divider = calc_pll_cs->min_vco_khz /
-+ pll_settings->adjusted_pix_clk;
-+ if ((min_post_divider *
-+ pll_settings->adjusted_pix_clk) <
-+ calc_pll_cs->min_vco_khz)
-+ min_post_divider++;
-+ }
-+
-+ max_post_divider = calc_pll_cs->max_pix_clock_pll_post_divider;
-+ if (max_post_divider * pll_settings->adjusted_pix_clk
-+ > calc_pll_cs->max_vco_khz)
-+ max_post_divider = calc_pll_cs->max_vco_khz /
-+ pll_settings->adjusted_pix_clk;
-+ }
-+
-+/* 2) Find Reference divider ranges
-+ * When SS is enabled, or for Display Port even without SS,
-+ * pll_settings->referenceDivider is not zero.
-+ * So calculate PPLL FB and fractional FB divider
-+ * using the passed reference divider*/
-+
-+ if (pll_settings->reference_divider) {
-+ min_ref_divider = pll_settings->reference_divider;
-+ max_ref_divider = pll_settings->reference_divider;
-+ } else {
-+ min_ref_divider = ((calc_pll_cs->ref_freq_khz
-+ / calc_pll_cs->max_pll_input_freq_khz)
-+ > calc_pll_cs->min_pll_ref_divider)
-+ ? calc_pll_cs->ref_freq_khz
-+ / calc_pll_cs->max_pll_input_freq_khz
-+ : calc_pll_cs->min_pll_ref_divider;
-+
-+ max_ref_divider = ((calc_pll_cs->ref_freq_khz
-+ / calc_pll_cs->min_pll_input_freq_khz)
-+ < calc_pll_cs->max_pll_ref_divider)
-+ ? calc_pll_cs->ref_freq_khz /
-+ calc_pll_cs->min_pll_input_freq_khz
-+ : calc_pll_cs->max_pll_ref_divider;
-+ }
-+
-+/* If some parameters are invalid we could have scenario when "min">"max"
-+ * which produced endless loop later.
-+ * We should investigate why we get the wrong parameters.
-+ * But to follow the similar logic when "adjustedPixelClock" is set to be 0
-+ * it is better to return here than cause system hang/watchdog timeout later.
-+ * ## SVS Wed 15 Jul 2009 */
-+
-+ if (min_post_divider > max_post_divider) {
-+ dal_logger_write(calc_pll_cs->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s Post divider range is invalid", __func__);
-+ return MAX_PLL_CALC_ERROR;
-+ }
-+
-+ if (min_ref_divider > max_ref_divider) {
-+ dal_logger_write(calc_pll_cs->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s Reference divider range is invalid", __func__);
-+ return MAX_PLL_CALC_ERROR;
-+ }
-+
-+/* 3) Try to find PLL dividers given ranges
-+ * starting with minimal error tolerance.
-+ * Increase error tolerance until PLL dividers found*/
-+ err_tolerance = MAX_PLL_CALC_ERROR;
-+
-+ while (!calc_pll_dividers_in_range(
-+ calc_pll_cs,
-+ pll_settings,
-+ min_ref_divider,
-+ max_ref_divider,
-+ min_post_divider,
-+ max_post_divider,
-+ err_tolerance))
-+ err_tolerance += (err_tolerance > 10)
-+ ? (err_tolerance / 10)
-+ : 1;
-+
-+ return err_tolerance;
-+}
-+
-+static bool calc_pll_clock_source_max_vco_construct(
-+ struct calc_pll_clock_source *calc_pll_cs,
-+ struct calc_pll_clock_source_init_data *init_data)
-+{
-+
-+ uint32_t i;
-+ struct firmware_info fw_info = { { 0 } };
-+ if (calc_pll_cs == NULL ||
-+ init_data == NULL ||
-+ init_data->bp == NULL)
-+ return false;
-+
-+ if (dal_bios_parser_get_firmware_info(
-+ init_data->bp,
-+ &fw_info) != BP_RESULT_OK)
-+ return false;
-+
-+ calc_pll_cs->ctx = init_data->ctx;
-+ calc_pll_cs->ref_freq_khz = fw_info.pll_info.crystal_frequency;
-+ calc_pll_cs->min_vco_khz =
-+ fw_info.pll_info.min_output_pxl_clk_pll_frequency;
-+ calc_pll_cs->max_vco_khz =
-+ fw_info.pll_info.max_output_pxl_clk_pll_frequency;
-+
-+ if (init_data->max_override_input_pxl_clk_pll_freq_khz != 0)
-+ calc_pll_cs->max_pll_input_freq_khz =
-+ init_data->max_override_input_pxl_clk_pll_freq_khz;
-+ else
-+ calc_pll_cs->max_pll_input_freq_khz =
-+ fw_info.pll_info.max_input_pxl_clk_pll_frequency;
-+
-+ if (init_data->min_override_input_pxl_clk_pll_freq_khz != 0)
-+ calc_pll_cs->min_pll_input_freq_khz =
-+ init_data->min_override_input_pxl_clk_pll_freq_khz;
-+ else
-+ calc_pll_cs->min_pll_input_freq_khz =
-+ fw_info.pll_info.min_input_pxl_clk_pll_frequency;
-+
-+ calc_pll_cs->min_pix_clock_pll_post_divider =
-+ init_data->min_pix_clk_pll_post_divider;
-+ calc_pll_cs->max_pix_clock_pll_post_divider =
-+ init_data->max_pix_clk_pll_post_divider;
-+ calc_pll_cs->min_pll_ref_divider =
-+ init_data->min_pll_ref_divider;
-+ calc_pll_cs->max_pll_ref_divider =
-+ init_data->max_pll_ref_divider;
-+
-+ if (init_data->num_fract_fb_divider_decimal_point == 0 ||
-+ init_data->num_fract_fb_divider_decimal_point_precision >
-+ init_data->num_fract_fb_divider_decimal_point) {
-+ dal_logger_write(calc_pll_cs->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "The dec point num or precision is incorrect!");
-+ return false;
-+ }
-+ if (init_data->num_fract_fb_divider_decimal_point_precision == 0) {
-+ dal_logger_write(calc_pll_cs->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Incorrect fract feedback divider precision num!");
-+ return false;
-+ }
-+
-+ calc_pll_cs->fract_fb_divider_decimal_points_num =
-+ init_data->num_fract_fb_divider_decimal_point;
-+ calc_pll_cs->fract_fb_divider_precision =
-+ init_data->num_fract_fb_divider_decimal_point_precision;
-+ calc_pll_cs->fract_fb_divider_factor = 1;
-+ for (i = 0; i < calc_pll_cs->fract_fb_divider_decimal_points_num; ++i)
-+ calc_pll_cs->fract_fb_divider_factor *= 10;
-+
-+ calc_pll_cs->fract_fb_divider_precision_factor = 1;
-+ for (
-+ i = 0;
-+ i < (calc_pll_cs->fract_fb_divider_decimal_points_num -
-+ calc_pll_cs->fract_fb_divider_precision);
-+ ++i)
-+ calc_pll_cs->fract_fb_divider_precision_factor *= 10;
-+
-+ return true;
-+}
-+
-+bool dal_calc_pll_clock_source_max_vco_init(
-+ struct calc_pll_clock_source *calc_pll_cs,
-+ struct calc_pll_clock_source_init_data *init_data)
-+{
-+ return calc_pll_clock_source_max_vco_construct(
-+ calc_pll_cs, init_data);
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/calc_pll_clock_source.h b/drivers/gpu/drm/amd/dal/dc/gpu/calc_pll_clock_source.h
-new file mode 100644
-index 0000000..be44d06
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/calc_pll_clock_source.h
-@@ -0,0 +1,79 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef __DAL_CALC_PLL_CLOCK_SOURCE_H__
-+#define __DAL_CALC_PLL_CLOCK_SOURCE_H__
-+
-+#include "include/clock_source_types.h"
-+
-+struct calc_pll_clock_source_init_data {
-+ struct bios_parser *bp;
-+ uint32_t min_pix_clk_pll_post_divider;
-+ uint32_t max_pix_clk_pll_post_divider;
-+ uint32_t min_pll_ref_divider;
-+ uint32_t max_pll_ref_divider;
-+ uint32_t min_override_input_pxl_clk_pll_freq_khz;
-+/* if not 0, override the firmware info */
-+
-+ uint32_t max_override_input_pxl_clk_pll_freq_khz;
-+/* if not 0, override the firmware info */
-+
-+ uint32_t num_fract_fb_divider_decimal_point;
-+/* number of decimal point for fractional feedback divider value */
-+
-+ uint32_t num_fract_fb_divider_decimal_point_precision;
-+/* number of decimal point to round off for fractional feedback divider value*/
-+ struct dc_context *ctx;
-+
-+};
-+#define CALC_PLL_CLK_SRC_ERR_TOLERANCE 1
-+struct calc_pll_clock_source {
-+ uint32_t ref_freq_khz;
-+ uint32_t min_pix_clock_pll_post_divider;
-+ uint32_t max_pix_clock_pll_post_divider;
-+ uint32_t min_pll_ref_divider;
-+ uint32_t max_pll_ref_divider;
-+
-+ uint32_t max_vco_khz;
-+ uint32_t min_vco_khz;
-+ uint32_t min_pll_input_freq_khz;
-+ uint32_t max_pll_input_freq_khz;
-+
-+ uint32_t fract_fb_divider_decimal_points_num;
-+ uint32_t fract_fb_divider_factor;
-+ uint32_t fract_fb_divider_precision;
-+ uint32_t fract_fb_divider_precision_factor;
-+ struct dc_context *ctx;
-+};
-+
-+
-+bool dal_calc_pll_clock_source_max_vco_init(
-+ struct calc_pll_clock_source *calc_pll_cs,
-+ struct calc_pll_clock_source_init_data *init_data);
-+
-+uint32_t dal_clock_source_calculate_pixel_clock_pll_dividers(
-+ struct calc_pll_clock_source *calc_pll_cs,
-+ struct pll_settings *pll_settings);
-+
-+
-+#endif /*__DAL_CALC_PLL_CLOCK_SOURCE_H__*/
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/clock_source.c b/drivers/gpu/drm/amd/dal/dc/gpu/clock_source.c
-new file mode 100644
-index 0000000..8e700ea
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/clock_source.c
-@@ -0,0 +1,649 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "include/adapter_service_interface.h"
-+#include "include/bios_parser_interface.h"
-+#include "include/grph_object_id.h"
-+#include "include/clock_source_interface.h"
-+#include "include/logger_interface.h"
-+
-+#include "clock_source.h"
-+#include "pll_clock_source.h"
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+#include "dce110/ext_clock_source_dce110.h"
-+#include "dce110/pll_clock_source_dce110.h"
-+#include "dce110/vce_clock_source_dce110.h"
-+#endif
-+
-+
-+struct clock_source *dal_clock_source_create(
-+ struct clock_source_init_data *clk_src_init_data)
-+{
-+ enum dce_version dce_ver =
-+ dal_adapter_service_get_dce_version(clk_src_init_data->as);
-+ enum clock_source_id clk_src_id =
-+ dal_graphics_object_id_get_clock_source_id(
-+ clk_src_init_data->clk_src_id);
-+ switch (dce_ver) {
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ break;
-+ case DCE_VERSION_11_0:
-+ {
-+ switch (clk_src_id) {
-+ case CLOCK_SOURCE_ID_PLL0:
-+ /* fall through */
-+ case CLOCK_SOURCE_ID_PLL1:
-+ /* fall through */
-+ case CLOCK_SOURCE_ID_PLL2:
-+ return dal_pll_clock_source_dce110_create(
-+ clk_src_init_data);
-+ case CLOCK_SOURCE_ID_EXTERNAL:
-+ return dal_ext_clock_source_dce110_create(
-+ clk_src_init_data);
-+ case CLOCK_SOURCE_ID_VCE:
-+ return dal_vce_clock_source_dce110_create(
-+ clk_src_init_data);
-+ default:
-+ return NULL;
-+ }
-+ }
-+ break;
-+#endif
-+ default:
-+ dal_logger_write(clk_src_init_data->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Clock Source (id %d): not supported DCE version %d",
-+ clk_src_id,
-+ dce_ver);
-+ ASSERT_CRITICAL(false);
-+ break;
-+ }
-+ return NULL;
-+}
-+
-+const struct spread_spectrum_data *dal_clock_source_get_ss_data_entry(
-+ struct clock_source *clk_src,
-+ enum signal_type signal,
-+ uint32_t pix_clk_khz)
-+{
-+
-+ uint32_t entrys_num;
-+ uint32_t i;
-+ struct spread_spectrum_data *ss_parm = NULL;
-+ struct spread_spectrum_data *ret = NULL;
-+
-+ switch (signal) {
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
-+ case SIGNAL_TYPE_DVI_DUAL_LINK:
-+ ss_parm = clk_src->dvi_ss_params;
-+ entrys_num = clk_src->dvi_ss_params_cnt;
-+ break;
-+
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ ss_parm = clk_src->hdmi_ss_params;
-+ entrys_num = clk_src->hdmi_ss_params_cnt;
-+ break;
-+
-+ case SIGNAL_TYPE_LVDS:
-+ ss_parm = clk_src->ep_ss_params;
-+ entrys_num = clk_src->ep_ss_params_cnt;
-+ break;
-+
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP:
-+ ss_parm = clk_src->dp_ss_params;
-+ entrys_num = clk_src->dp_ss_params_cnt;
-+ break;
-+
-+ default:
-+ ss_parm = NULL;
-+ entrys_num = 0;
-+ break;
-+ }
-+
-+ if (ss_parm == NULL)
-+ return ret;
-+
-+ for (i = 0; i < entrys_num; ++i, ++ss_parm) {
-+ if (ss_parm->freq_range_khz >= pix_clk_khz) {
-+ ret = ss_parm;
-+ break;
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+bool dal_clock_source_base_adjust_dto_pix_rate(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ uint32_t requested_pix_clk_hz)
-+{
-+ return false;
-+}
-+
-+/* Adjust clock to match given pixel rate (SS/DeepColor compensated)*/
-+bool dal_clock_source_base_adjust_pll_pixel_rate(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ uint32_t requestedPixelClockInHz)
-+{
-+ return false;
-+}
-+
-+static uint32_t retrieve_raw_pix_rate_hz(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params)
-+{
-+ if (dc_is_dp_signal(pix_clk_params->signal_type))
-+ return clk_src->funcs->retrieve_dto_pix_rate_hz(
-+ clk_src,
-+ pix_clk_params);
-+ else
-+ return clk_src->funcs->retrieve_pll_pix_rate_hz(
-+ clk_src,
-+ pix_clk_params);
-+}
-+
-+
-+
-+bool dal_clock_source_adjust_pxl_clk_by_pxl_amount(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ int32_t pix_num)
-+{
-+
-+ uint32_t cur_pix_rate_hz;
-+ uint32_t reqested_pix_rate_hz;
-+ bool success = false;
-+
-+ if (pix_clk_params == NULL)
-+ return false;
-+
-+ cur_pix_rate_hz = retrieve_raw_pix_rate_hz(clk_src, pix_clk_params);
-+ reqested_pix_rate_hz = cur_pix_rate_hz + pix_num;
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_SYNC,
-+ LOG_MINOR_SYNC_HW_CLOCK_ADJUST,
-+ "%s[start]: Current(Raw): %u,%03u,%03uHz, Requested(Raw): %u,%03u,%03uHz\n",
-+ __func__,
-+ (cur_pix_rate_hz / 1000000),
-+ (cur_pix_rate_hz / 1000) % 1000,
-+ (cur_pix_rate_hz % 1000),
-+ (reqested_pix_rate_hz / 1000000),
-+ (reqested_pix_rate_hz / 1000) % 1000,
-+ (reqested_pix_rate_hz % 1000));
-+
-+ if (dc_is_dp_signal(pix_clk_params->signal_type))
-+ success = clk_src->funcs->adjust_dto_pixel_rate(clk_src,
-+ pix_clk_params,
-+ reqested_pix_rate_hz);
-+ else
-+ success = clk_src->funcs->adjust_pll_pixel_rate(
-+ clk_src,
-+ pix_clk_params,
-+ reqested_pix_rate_hz);
-+
-+ cur_pix_rate_hz = retrieve_raw_pix_rate_hz(clk_src, pix_clk_params);
-+
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_SYNC,
-+ LOG_MINOR_SYNC_HW_CLOCK_ADJUST,
-+ "%s[end]: Current(Raw): %u,%03u,%03uHz, Requested(Raw): %u,%03u,%03uHz\n\n",
-+ __func__,
-+ (cur_pix_rate_hz / 1000000),
-+ (cur_pix_rate_hz / 1000) % 1000,
-+ (cur_pix_rate_hz % 1000),
-+ (reqested_pix_rate_hz / 1000000),
-+ (reqested_pix_rate_hz / 1000) % 1000,
-+ (reqested_pix_rate_hz % 1000));
-+
-+ return success;
-+}
-+
-+/***************************/
-+/* private methods section */
-+/***************************/
-+
-+void dal_clock_source_get_ss_info_from_atombios(
-+ struct clock_source *clk_src,
-+ enum as_signal_type as_signal,
-+ struct spread_spectrum_data *spread_spectrum_data[],
-+ uint32_t *ss_entries_num)
-+{
-+ enum bp_result bp_result = BP_RESULT_FAILURE;
-+ struct spread_spectrum_info *ss_info;
-+ struct spread_spectrum_data *ss_data;
-+ struct spread_spectrum_info *ss_info_cur;
-+ struct spread_spectrum_data *ss_data_cur;
-+ uint32_t i;
-+
-+ if (ss_entries_num == NULL) {
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_SYNC,
-+ LOG_MINOR_SYNC_HW_CLOCK_ADJUST,
-+ "Invalid entry !!!\n");
-+ return;
-+ }
-+ if (spread_spectrum_data == NULL) {
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_SYNC,
-+ LOG_MINOR_SYNC_HW_CLOCK_ADJUST,
-+ "Invalid array pointer!!!\n");
-+ return;
-+ }
-+
-+ spread_spectrum_data[0] = NULL;
-+ *ss_entries_num = 0;
-+
-+ *ss_entries_num = dal_bios_parser_get_ss_entry_number(
-+ clk_src->bios_parser,
-+ as_signal);
-+ if (*ss_entries_num == 0)
-+ return;
-+
-+ ss_info = dc_service_alloc(clk_src->ctx, sizeof(struct spread_spectrum_info)
-+ * (*ss_entries_num));
-+ ss_info_cur = ss_info;
-+ if (ss_info == NULL)
-+ return;
-+
-+ ss_data = dc_service_alloc(clk_src->ctx, sizeof(struct spread_spectrum_data) *
-+ (*ss_entries_num));
-+ if (ss_data == NULL)
-+ goto out_free_info;
-+
-+ for (i = 0, ss_info_cur = ss_info;
-+ i < (*ss_entries_num);
-+ ++i, ++ss_info_cur) {
-+ bp_result = dal_bios_parser_get_spread_spectrum_info(
-+ clk_src->bios_parser,
-+ as_signal,
-+ i,
-+ ss_info_cur);
-+ if (bp_result != BP_RESULT_OK)
-+ goto out_free_data;
-+ }
-+
-+ for (i = 0, ss_info_cur = ss_info, ss_data_cur = ss_data;
-+ i < (*ss_entries_num);
-+ ++i, ++ss_info_cur, ++ss_data_cur) {
-+
-+ if (ss_info_cur->type.STEP_AND_DELAY_INFO != false) {
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_SYNC,
-+ LOG_MINOR_SYNC_HW_CLOCK_ADJUST,
-+ "Invalid ATOMBIOS SS Table!!!\n");
-+ goto out_free_data;
-+ }
-+
-+ /* for HDMI check SS percentage,
-+ * if it is > 6 (0.06%), the ATOMBIOS table info is invalid*/
-+ if (as_signal == AS_SIGNAL_TYPE_HDMI
-+ && ss_info_cur->spread_spectrum_percentage > 6){
-+ /* invalid input, do nothing */
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_SYNC,
-+ LOG_MINOR_SYNC_HW_CLOCK_ADJUST,
-+ "Invalid SS percentage ");
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_SYNC,
-+ LOG_MINOR_SYNC_HW_CLOCK_ADJUST,
-+ "for HDMI in ATOMBIOS info Table!!!\n");
-+ continue;
-+ }
-+ if (ss_info_cur->spread_percentage_divider == 1000) {
-+ /* Keep previous precision from ATOMBIOS for these
-+ * in case new precision set by ATOMBIOS for these
-+ * (otherwise all code in DCE specific classes
-+ * for all previous ASICs would need
-+ * to be updated for SS calculations,
-+ * Audio SS compensation and DP DTO SS compensation
-+ * which assumes fixed SS percentage Divider = 100)*/
-+ ss_info_cur->spread_spectrum_percentage /= 10;
-+ ss_info_cur->spread_percentage_divider = 100;
-+ }
-+
-+ ss_data_cur->freq_range_khz = ss_info_cur->target_clock_range;
-+ ss_data_cur->percentage =
-+ ss_info_cur->spread_spectrum_percentage;
-+ ss_data_cur->percentage_divider =
-+ ss_info_cur->spread_percentage_divider;
-+ ss_data_cur->modulation_freq_hz =
-+ ss_info_cur->spread_spectrum_range;
-+
-+ if (ss_info_cur->type.CENTER_MODE)
-+ ss_data_cur->flags.CENTER_SPREAD = 1;
-+
-+ if (ss_info_cur->type.EXTERNAL)
-+ ss_data_cur->flags.EXTERNAL_SS = 1;
-+
-+ }
-+
-+ *spread_spectrum_data = ss_data;
-+ dc_service_free(clk_src->ctx, ss_info);
-+ return;
-+
-+out_free_data:
-+ dc_service_free(clk_src->ctx, ss_data);
-+ *ss_entries_num = 0;
-+out_free_info:
-+ dc_service_free(clk_src->ctx, ss_info);
-+}
-+
-+uint32_t dal_clock_source_base_retrieve_dto_pix_rate_hz(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params)
-+{
-+ return 0;
-+}
-+
-+
-+uint32_t dal_clock_source_base_retrieve_pll_pix_rate_hz(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params)
-+{
-+ return 0;
-+}
-+
-+/*****************************/
-+/* interface methods section */
-+/*****************************/
-+
-+enum clock_source_id dal_clock_source_get_id(
-+ const struct clock_source *clk_src)
-+{
-+ return clk_src->clk_src_id;
-+}
-+
-+bool dal_clock_source_is_clk_src_with_fixed_freq(
-+ const struct clock_source *clk_src)
-+{
-+ return clk_src->is_clock_source_with_fixed_freq;
-+}
-+
-+const struct graphics_object_id dal_clock_source_get_graphics_object_id(
-+ const struct clock_source *clk_src)
-+{
-+ return clk_src->id;
-+}
-+
-+enum clock_sharing_level dal_clock_souce_get_clk_sharing_lvl(
-+ const struct clock_source *clk_src)
-+{
-+ return clk_src->clk_sharing_lvl;
-+}
-+
-+uint32_t dal_clock_source_get_pix_clk_dividers(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings)
-+{
-+ return clk_src->funcs->
-+ get_pix_clk_dividers(clk_src, pix_clk_params, pll_settings);
-+}
-+
-+bool dal_clock_source_program_pix_clk(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings)
-+{
-+ return clk_src->funcs->
-+ program_pix_clk(clk_src, pix_clk_params, pll_settings);
-+}
-+
-+/* TODO save/restore FP was here */
-+bool dal_clock_source_adjust_pxl_clk_by_ref_pixel_rate(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ uint32_t pix_rate_hz)
-+{
-+ uint32_t current_pix_rate_hz = 0;
-+ uint32_t raw_cur_pix_rate_hz = 0;
-+ uint32_t raw_pix_rate_hz = pix_rate_hz;
-+ bool success = false;
-+
-+ if (pix_clk_params == NULL || pix_rate_hz == 0)
-+ return false;
-+
-+ current_pix_rate_hz = retrieve_raw_pix_rate_hz(
-+ clk_src,
-+ pix_clk_params);
-+ raw_cur_pix_rate_hz = current_pix_rate_hz;
-+
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_SYNC,
-+ LOG_MINOR_SYNC_HW_CLOCK_ADJUST,
-+ "%s[start]: Current: %u,%03u,%03uHz, Requested: %u,%03u,%03uHz\n",
-+ __func__,
-+ (current_pix_rate_hz / 1000000),
-+ (current_pix_rate_hz / 1000) % 1000,
-+ (current_pix_rate_hz % 1000),
-+ (pix_rate_hz / 1000000),
-+ (pix_rate_hz / 1000) % 1000,
-+ (pix_rate_hz % 1000));
-+
-+ if (dc_is_dp_signal(pix_clk_params->signal_type))
-+ success = clk_src->funcs->adjust_dto_pixel_rate(
-+ clk_src,
-+ pix_clk_params,
-+ raw_pix_rate_hz);
-+ else
-+ success = clk_src->funcs->adjust_pll_pixel_rate(
-+ clk_src,
-+ pix_clk_params,
-+ raw_pix_rate_hz);
-+
-+ if (dc_is_dp_signal(pix_clk_params->signal_type))
-+ raw_cur_pix_rate_hz = clk_src->funcs->
-+ retrieve_dto_pix_rate_hz(
-+ clk_src,
-+ pix_clk_params);
-+ else
-+ raw_cur_pix_rate_hz = clk_src->funcs->
-+ retrieve_pll_pix_rate_hz(
-+ clk_src,
-+ pix_clk_params);
-+
-+ current_pix_rate_hz = raw_cur_pix_rate_hz;
-+
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_SYNC,
-+ LOG_MINOR_SYNC_HW_CLOCK_ADJUST,
-+ "%s[end]: Current: %u,%03u,%03uHz, Requested: %u,%03u,%03uHz\n",
-+ __func__,
-+ (current_pix_rate_hz / 1000000),
-+ (current_pix_rate_hz / 1000) % 1000,
-+ (current_pix_rate_hz % 1000),
-+ (pix_rate_hz / 1000000),
-+ (pix_rate_hz / 1000) % 1000,
-+ (pix_rate_hz % 1000));
-+
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_SYNC,
-+ LOG_MINOR_SYNC_HW_CLOCK_ADJUST,
-+ "%s[end]: Current(Raw): %u,%03u,%03uHz, Requested(Raw): %u,%03u,%03uHz\n\n",
-+ __func__,
-+ (raw_cur_pix_rate_hz / 1000000),
-+ (raw_cur_pix_rate_hz / 1000) % 1000,
-+ (raw_cur_pix_rate_hz % 1000),
-+ (raw_pix_rate_hz / 1000000),
-+ (raw_pix_rate_hz / 1000) % 1000,
-+ (raw_pix_rate_hz % 1000));
-+
-+ return success;
-+}
-+
-+/* TODO store/restore FP was here*/
-+bool dal_clock_source_adjust_pxl_clk_by_pix_amount(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ int32_t pix_num)
-+{
-+ bool success = false;
-+ uint32_t requested_pix_rate_hz;
-+ uint32_t cur_pix_rate_hz = retrieve_raw_pix_rate_hz(
-+ clk_src,
-+ pix_clk_params);
-+ requested_pix_rate_hz = cur_pix_rate_hz + pix_num;
-+
-+ if (pix_clk_params == NULL)
-+ return false;
-+
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_SYNC,
-+ LOG_MINOR_SYNC_HW_CLOCK_ADJUST,
-+ "%s[start]: Current(Raw): %u,%03u,%03uHz, Requested(Raw): %u,%03u,%03uHz\n",
-+ __func__,
-+ (cur_pix_rate_hz / 1000000),
-+ (cur_pix_rate_hz / 1000) % 1000,
-+ (cur_pix_rate_hz % 1000),
-+ (requested_pix_rate_hz / 1000000),
-+ (requested_pix_rate_hz / 1000) % 1000,
-+ (requested_pix_rate_hz % 1000));
-+
-+ if (dc_is_dp_signal(pix_clk_params->signal_type))
-+ success = clk_src->funcs->adjust_dto_pixel_rate(
-+ clk_src,
-+ pix_clk_params,
-+ requested_pix_rate_hz);
-+ else
-+ success = clk_src->funcs->adjust_pll_pixel_rate(
-+ clk_src,
-+ pix_clk_params,
-+ requested_pix_rate_hz);
-+
-+ cur_pix_rate_hz = retrieve_raw_pix_rate_hz(clk_src, pix_clk_params);
-+
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_SYNC,
-+ LOG_MINOR_SYNC_HW_CLOCK_ADJUST,
-+ "%s[end]: Current(Raw): %u,%03u,%03uHz,Requested(Raw): %u,%03u,%03uHz\n\n",
-+ __func__,
-+ (cur_pix_rate_hz / 1000000),
-+ (cur_pix_rate_hz / 1000) % 1000,
-+ (cur_pix_rate_hz % 1000),
-+ (requested_pix_rate_hz / 1000000),
-+ (requested_pix_rate_hz / 1000) % 1000,
-+ (requested_pix_rate_hz % 1000));
-+
-+ return success;
-+}
-+
-+/* TODO save/restore FP was here*/
-+uint32_t dal_clock_source_retrieve_pix_rate_hz(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params)
-+{
-+ uint32_t pixel_rate_hz = 0;
-+
-+ if (pix_clk_params == NULL)
-+ return pixel_rate_hz;
-+
-+ if (dc_is_dp_signal(pix_clk_params->signal_type))
-+ pixel_rate_hz = clk_src->funcs->retrieve_dto_pix_rate_hz(
-+ clk_src,
-+ pix_clk_params);
-+ else
-+ pixel_rate_hz = clk_src->funcs->retrieve_pll_pix_rate_hz(
-+ clk_src,
-+ pix_clk_params);
-+
-+
-+ return pixel_rate_hz;
-+}
-+
-+bool dal_clock_source_construct(
-+ struct clock_source *clk_src,
-+ struct clock_source_init_data *clk_src_init_data)
-+{
-+ if (clk_src_init_data == NULL || clk_src_init_data->as == NULL)
-+ return false;
-+ clk_src->ctx = clk_src_init_data->ctx;
-+ clk_src->id = clk_src_init_data->clk_src_id;
-+ clk_src->adapter_service = clk_src_init_data->as;
-+ clk_src->bios_parser = dal_adapter_service_get_bios_parser(
-+ clk_src_init_data->as);
-+ clk_src->turn_off_ds = false;
-+ clk_src->clk_src_id = dal_graphics_object_id_get_clock_source_id(
-+ clk_src_init_data->clk_src_id);
-+ clk_src->is_gen_lock_capable = true;
-+/*NOTE is_gen_lock_capable is false only for ext clock source dce80 */
-+
-+ clk_src->ep_ss_params = NULL;
-+ clk_src->dp_ss_params = NULL;
-+ clk_src->hdmi_ss_params = NULL;
-+ clk_src->hdmi_ss_params = NULL;
-+ clk_src->ep_ss_params_cnt = 0;
-+ clk_src->dp_ss_params_cnt = 0;
-+ clk_src->hdmi_ss_params_cnt = 0;
-+ clk_src->dvi_ss_params_cnt = 0;
-+ clk_src->output_signals = SIGNAL_TYPE_ALL;
-+ clk_src->input_signals = SIGNAL_TYPE_ALL;
-+
-+ return true;
-+}
-+
-+void dal_clock_source_destroy(struct clock_source **clk_src)
-+{
-+ if (!clk_src || !(*clk_src))
-+ return;
-+
-+ (*clk_src)->funcs->destroy(clk_src);
-+
-+ *clk_src = NULL;
-+}
-+
-+bool dal_clock_source_is_input_signal_supported(
-+ struct clock_source *clk_src,
-+ enum signal_type signal_type)
-+{
-+ /* TODO do we need this in clock_source ?? */
-+ return (clk_src->input_signals & signal_type) != 0;
-+}
-+
-+bool dal_clock_source_is_output_signal_supported(
-+ const struct clock_source *clk_src,
-+ enum signal_type signal_type)
-+{
-+ return (clk_src->output_signals & signal_type) != 0;
-+}
-+
-+bool dal_clock_source_is_gen_lock_capable(struct clock_source *clk_src)
-+{
-+ return clk_src->is_gen_lock_capable;
-+}
-+
-+bool dal_clock_source_power_down_pll(struct clock_source *clk_src,
-+ enum controller_id controller_id)
-+{
-+ return clk_src->funcs->power_down_pll(clk_src, controller_id);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/clock_source.h b/drivers/gpu/drm/amd/dal/dc/gpu/clock_source.h
-new file mode 100644
-index 0000000..0a83874
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/clock_source.h
-@@ -0,0 +1,136 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_CLOCK_SOURCE_H__
-+#define __DAL_CLOCK_SOURCE_H__
-+
-+#include "include/adapter_service_types.h"
-+#include "include/bios_parser_types.h"
-+#include "include/clock_source_interface.h"
-+#include "include/clock_source_types.h"
-+
-+struct spread_spectrum_data {
-+ uint32_t percentage; /*> In unit of 0.01% or 0.001%*/
-+ uint32_t percentage_divider; /*> 100 or 1000 */
-+ uint32_t freq_range_khz;
-+ uint32_t modulation_freq_hz;
-+
-+ struct spread_spectrum_flags flags;
-+};
-+
-+struct clock_source_impl {
-+ bool (*switch_dp_clock_source)(
-+ struct clock_source *clk_src,
-+ enum controller_id,
-+ enum clock_source_id);
-+ bool (*adjust_pll_pixel_rate)(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ uint32_t requested_pix_clk_hz);
-+ bool (*adjust_dto_pixel_rate)(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ uint32_t requested_clk_freq_hz);
-+ uint32_t (*retrieve_dto_pix_rate_hz)(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params);
-+ uint32_t (*retrieve_pll_pix_rate_hz)(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params);
-+
-+ uint32_t (*get_pix_clk_dividers)(struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings);
-+ bool (*program_pix_clk)(struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings);
-+ bool (*power_down_pll)(struct clock_source *clk_src,
-+ enum controller_id);
-+ void (*destroy)(struct clock_source **clk_src);
-+};
-+
-+void dal_clock_source_get_ss_info_from_atombios(
-+ struct clock_source *clk_src,
-+ enum as_signal_type as_signal,
-+ struct spread_spectrum_data *ss_data[],
-+ uint32_t *ss_entries_num);
-+uint32_t dal_clock_source_base_retrieve_dto_pix_rate_hz(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params);
-+const struct spread_spectrum_data *dal_clock_source_get_ss_data_entry(
-+ struct clock_source *clk_src,
-+ enum signal_type signal,
-+ uint32_t pix_clk_khz);
-+/* for PLL and EXT clock sources */
-+struct registers {
-+ uint32_t dp_dtox_phase;
-+ uint32_t dp_dtox_modulo;
-+ uint32_t crtcx_pixel_rate_cntl;
-+};
-+
-+struct clock_source {
-+ const struct clock_source_impl *funcs;
-+ struct graphics_object_id id;
-+ enum clock_source_id clk_src_id;
-+ struct adapter_service *adapter_service;
-+ struct bios_parser *bios_parser;
-+
-+ struct spread_spectrum_data *ep_ss_params;
-+ uint32_t ep_ss_params_cnt;
-+ struct spread_spectrum_data *dp_ss_params;
-+ uint32_t dp_ss_params_cnt;
-+
-+ struct spread_spectrum_data *hdmi_ss_params;
-+ uint32_t hdmi_ss_params_cnt;
-+
-+ struct spread_spectrum_data *dvi_ss_params;
-+ uint32_t dvi_ss_params_cnt;
-+
-+ uint32_t output_signals;
-+ uint32_t input_signals;
-+
-+ bool turn_off_ds;
-+ bool is_gen_lock_capable; /*replacement for virtual method*/
-+ bool is_clock_source_with_fixed_freq; /*replacement for virtual method*/
-+ enum clock_sharing_level clk_sharing_lvl;
-+ struct dc_context *ctx;
-+};
-+
-+bool dal_clock_source_construct(
-+ struct clock_source *clk_src,
-+ struct clock_source_init_data *clk_src_init_data);
-+bool dal_clock_source_base_adjust_pll_pixel_rate(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ uint32_t requested_pix_clk_hz);
-+bool dal_clock_source_base_adjust_dto_pix_rate(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ uint32_t requested_pix_clk_hz);
-+uint32_t dal_clock_source_base_retrieve_pll_pix_rate_hz(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dc_clock_generator.c b/drivers/gpu/drm/amd/dal/dc/gpu/dc_clock_generator.c
-new file mode 100644
-index 0000000..f124dba
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dc_clock_generator.c
-@@ -0,0 +1,92 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "dc_clock_generator.h"
-+
-+void dal_dc_clock_generator_destroy(struct dc_clock_generator **dc)
-+{
-+ if (dc == NULL || *dc == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ (*dc)->funcs->destroy(dc);
-+
-+ *dc = NULL;
-+}
-+
-+void dal_dc_clock_generator_set_display_pipe_mapping(
-+ struct dc_clock_generator *dc_clk_gen,
-+ struct dccg_mapping_params *params)
-+{
-+ dc_clk_gen->funcs->set_display_pipe_mapping(dc_clk_gen, params);
-+}
-+
-+bool dal_dc_clock_generator_get_dp_ref_clk_ds_params(
-+ struct dc_clock_generator *dc_clk_gen,
-+ struct dccg_dp_ref_clk_ds_params *params)
-+{
-+ return dc_clk_gen->funcs->get_dp_ref_clk_ds_params(dc_clk_gen, params);
-+}
-+
-+bool dal_dc_clock_generator_enable_gtc_counter(
-+ struct dc_clock_generator *dc_clk_gen,
-+ uint32_t dprefclk)
-+{
-+ return dc_clk_gen->funcs->enable_gtc_counter(dc_clk_gen, dprefclk);
-+}
-+
-+void dal_dc_clock_generator_disable_gtc_counter(
-+ struct dc_clock_generator *dc_clk_gen)
-+{
-+ dc_clk_gen->funcs->disable_gtc_counter(dc_clk_gen);
-+}
-+
-+void dal_dc_clock_generator_set_gtc_group_offset(
-+ struct dc_clock_generator *dc_clk_gen,
-+ enum gtc_group group_num,
-+ uint32_t offset)
-+{
-+ dc_clk_gen->funcs->set_gtc_group_offset(dc_clk_gen, group_num, offset);
-+}
-+
-+void dal_dc_clock_generator_base_set_display_pipe_mapping(
-+ struct dc_clock_generator *base,
-+ struct dccg_mapping_params *params)
-+{
-+
-+}
-+
-+bool dal_dc_clock_generator_construct_base(
-+ struct dc_clock_generator *base,
-+ struct dc_context *ctx
-+)
-+{
-+ base->ctx = ctx;
-+ return true;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dc_clock_generator.h b/drivers/gpu/drm/amd/dal/dc/gpu/dc_clock_generator.h
-new file mode 100644
-index 0000000..d1bf1af
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dc_clock_generator.h
-@@ -0,0 +1,63 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DC_CLOCK_GENERATOR_H__
-+#define __DAL_DC_CLOCK_GENERATOR_H__
-+
-+#include "include/dc_clock_generator_interface.h"
-+
-+struct dc_clock_generator_funcs {
-+ void (*destroy)(struct dc_clock_generator **to_destroy);
-+
-+ void (*set_display_pipe_mapping)(
-+ struct dc_clock_generator *dc_clk_gen,
-+ struct dccg_mapping_params *params);
-+
-+ bool (*get_dp_ref_clk_ds_params)(
-+ struct dc_clock_generator *dc_clk_gen,
-+ struct dccg_dp_ref_clk_ds_params *params);
-+ bool (*enable_gtc_counter)(
-+ struct dc_clock_generator *dc_clk_gen,
-+ uint32_t dprefclk);
-+ void (*disable_gtc_counter)(
-+ struct dc_clock_generator *dc_clk_gen);
-+ void (*set_gtc_group_offset)(
-+ struct dc_clock_generator *dc_clk_gen,
-+ enum gtc_group group_num,
-+ uint32_t offset);
-+};
-+struct dc_clock_generator {
-+ const struct dc_clock_generator_funcs *funcs;
-+ struct dc_context *ctx;
-+};
-+bool dal_dc_clock_generator_construct_base(
-+ struct dc_clock_generator *base,
-+ struct dc_context *ctx
-+);
-+void dal_dc_clock_generator_base_set_display_pipe_mapping(
-+ struct dc_clock_generator *base,
-+ struct dccg_mapping_params *params);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce110/dc_clock_gating_dce110.c b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/dc_clock_gating_dce110.c
-new file mode 100644
-index 0000000..e2d4228
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/dc_clock_gating_dce110.c
-@@ -0,0 +1,90 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "include/logger_interface.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+#include "dc_clock_gating_dce110.h"
-+
-+/******************************************************************************
-+ * Macro definitions
-+ *****************************************************************************/
-+
-+#define NOT_IMPLEMENTED() DAL_LOGGER_NOT_IMPL(LOG_MINOR_COMPONENT_GPU, \
-+ "%s:%s()\n", __FILE__, __func__)
-+
-+/******************************************************************************
-+ * static functions
-+ *****************************************************************************/
-+static void force_hw_base_light_sleep(struct dc_context *ctx)
-+{
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+
-+
-+ addr = mmDC_MEM_GLOBAL_PWR_REQ_CNTL;
-+ /* Read the mmDC_MEM_GLOBAL_PWR_REQ_CNTL to get the currently
-+ * programmed DC_MEM_GLOBAL_PWR_REQ_DIS*/
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_MEM_GLOBAL_PWR_REQ_CNTL,
-+ DC_MEM_GLOBAL_PWR_REQ_DIS);
-+
-+ dal_write_reg(ctx, addr, value);
-+
-+}
-+
-+static void enable_hw_base_light_sleep(struct dc_context *ctx)
-+{
-+ NOT_IMPLEMENTED();
-+}
-+
-+static void disable_sw_manual_control_light_sleep(
-+ struct dc_context *ctx)
-+{
-+ NOT_IMPLEMENTED();
-+}
-+
-+/******************************************************************************
-+ * public functions
-+ *****************************************************************************/
-+
-+void dal_dc_clock_gating_dce110_power_up(
-+ struct dc_context *ctx,
-+ bool enable)
-+{
-+ if (enable) {
-+ enable_hw_base_light_sleep(ctx);
-+ disable_sw_manual_control_light_sleep(ctx);
-+ } else {
-+ force_hw_base_light_sleep(ctx);
-+ }
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce110/dc_clock_gating_dce110.h b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/dc_clock_gating_dce110.h
-new file mode 100644
-index 0000000..1bfd75a
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/dc_clock_gating_dce110.h
-@@ -0,0 +1,33 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DC_CLOCK_GATING_DCE110_H__
-+#define __DAL_DC_CLOCK_GATING_DCE110_H__
-+
-+void dal_dc_clock_gating_dce110_power_up(
-+ struct dc_context *ctx,
-+ bool enable);
-+
-+#endif /* __DAL_DC_CLOCK_GATING_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce110/display_clock_dce110.c b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/display_clock_dce110.c
-new file mode 100644
-index 0000000..e582ba0
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/display_clock_dce110.c
-@@ -0,0 +1,958 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "include/adapter_service_interface.h"
-+#include "include/bios_parser_interface.h"
-+#include "include/fixed32_32.h"
-+#include "include/logger_interface.h"
-+
-+#include "../divider_range.h"
-+
-+#include "display_clock_dce110.h"
-+
-+#define FROM_DISPLAY_CLOCK(base) \
-+ container_of(base, struct display_clock_dce110, disp_clk_base)
-+
-+static struct state_dependent_clocks max_clks_by_state[] = {
-+/*( dvo not exist in KV)*/
-+/*ClocksStateInvalid - should not be used*/
-+{ .display_clk_khz = 0, .pixel_clk_khz = 0, .dvo_clk_khz = 0 },
-+/*ClocksStateUltraLow - currently by HW design team not supposed to be used*/
-+{ .display_clk_khz = 352000, .pixel_clk_khz = 330000, .dvo_clk_khz = 0 },
-+/*ClocksStateLow*/
-+{ .display_clk_khz = 352000, .pixel_clk_khz = 330000, .dvo_clk_khz = 0 },
-+/*ClocksStateNominal*/
-+{ .display_clk_khz = 467000, .pixel_clk_khz = 400000, .dvo_clk_khz = 0 },
-+/*ClocksStatePerformance*/
-+{ .display_clk_khz = 643000, .pixel_clk_khz = 400000, .dvo_clk_khz = 0 } };
-+
-+
-+/* Starting point for each divider range.*/
-+enum divider_range_start {
-+ DIVIDER_RANGE_01_START = 200, /* 2.00*/
-+ DIVIDER_RANGE_02_START = 1600, /* 16.00*/
-+ DIVIDER_RANGE_03_START = 3200, /* 32.00*/
-+ DIVIDER_RANGE_SCALE_FACTOR = 100 /* Results are scaled up by 100.*/
-+};
-+
-+/* Array identifiers and count for the divider ranges.*/
-+enum divider_range_count {
-+ DIVIDER_RANGE_01 = 0,
-+ DIVIDER_RANGE_02,
-+ DIVIDER_RANGE_03,
-+ DIVIDER_RANGE_MAX /* == 3*/
-+};
-+
-+/* Ranges for divider identifiers (Divider ID or DID)
-+ mmDENTIST_DISPCLK_CNTL.DENTIST_DISPCLK_WDIVIDER*/
-+enum divider_id_register_setting {
-+ DIVIDER_RANGE_01_BASE_DIVIDER_ID = 0X08,
-+ DIVIDER_RANGE_02_BASE_DIVIDER_ID = 0X40,
-+ DIVIDER_RANGE_03_BASE_DIVIDER_ID = 0X60,
-+ DIVIDER_RANGE_MAX_DIVIDER_ID = 0X80
-+};
-+
-+/* Step size between each divider within a range.
-+ Incrementing the DENTIST_DISPCLK_WDIVIDER by one
-+ will increment the divider by this much.*/
-+enum divider_range_step_size {
-+ DIVIDER_RANGE_01_STEP_SIZE = 25, /* 0.25*/
-+ DIVIDER_RANGE_02_STEP_SIZE = 50, /* 0.50*/
-+ DIVIDER_RANGE_03_STEP_SIZE = 100 /* 1.00 */
-+};
-+
-+static struct divider_range divider_ranges[DIVIDER_RANGE_MAX];
-+
-+#define DCE110_DFS_BYPASS_THRESHOLD_KHZ 400000
-+/*****************************************************************************
-+ * static functions
-+ *****************************************************************************/
-+
-+/*
-+ * store_max_clocks_state
-+ *
-+ * @brief
-+ * Cache the clock state
-+ *
-+ * @param
-+ * struct display_clock *base - [out] cach the state in this structure
-+ * enum clocks_state max_clocks_state - [in] state to be stored
-+ */
-+static void store_max_clocks_state(
-+ struct display_clock *base,
-+ enum clocks_state max_clocks_state)
-+{
-+ struct display_clock_dce110 *dc = DCLCK110_FROM_BASE(base);
-+
-+ switch (max_clocks_state) {
-+ case CLOCKS_STATE_LOW:
-+ case CLOCKS_STATE_NOMINAL:
-+ case CLOCKS_STATE_PERFORMANCE:
-+ case CLOCKS_STATE_ULTRA_LOW:
-+ dc->max_clks_state = max_clocks_state;
-+ break;
-+
-+ case CLOCKS_STATE_INVALID:
-+ default:
-+ /*Invalid Clocks State!*/
-+ ASSERT_CRITICAL(false);
-+ break;
-+ }
-+}
-+
-+static enum clocks_state get_min_clocks_state(struct display_clock *base)
-+{
-+ return base->cur_min_clks_state;
-+}
-+
-+static bool set_min_clocks_state(
-+ struct display_clock *base,
-+ enum clocks_state clocks_state)
-+{
-+ struct display_clock_dce110 *dc = DCLCK110_FROM_BASE(base);
-+
-+ if (clocks_state > dc->max_clks_state) {
-+ /*Requested state exceeds max supported state.*/
-+ dal_logger_write(base->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Requested state exceeds max supported state");
-+ return false;
-+ } else if (clocks_state == base->cur_min_clks_state) {
-+ /*if we're trying to set the same state, we can just return
-+ * since nothing needs to be done*/
-+ return true;
-+ }
-+
-+ base->cur_min_clks_state = clocks_state;
-+
-+ return true;
-+}
-+
-+static uint32_t get_dp_ref_clk_frequency(struct display_clock *dc)
-+{
-+ uint32_t dispclk_cntl_value;
-+ uint32_t dp_ref_clk_cntl_value;
-+ uint32_t dp_ref_clk_cntl_src_sel_value;
-+ uint32_t dp_ref_clk_khz = 600000;
-+ uint32_t target_div = INVALID_DIVIDER;
-+ struct display_clock_dce110 *disp_clk = FROM_DISPLAY_CLOCK(dc);
-+
-+ /* ASSERT DP Reference Clock source is from DFS*/
-+ dp_ref_clk_cntl_value = dal_read_reg(dc->ctx,
-+ mmDPREFCLK_CNTL);
-+
-+ dp_ref_clk_cntl_src_sel_value =
-+ get_reg_field_value(
-+ dp_ref_clk_cntl_value,
-+ DPREFCLK_CNTL, DPREFCLK_SRC_SEL);
-+
-+ ASSERT(dp_ref_clk_cntl_src_sel_value == 0);
-+
-+ /* Read the mmDENTIST_DISPCLK_CNTL to get the currently
-+ * programmed DID DENTIST_DPREFCLK_WDIVIDER*/
-+ dispclk_cntl_value = dal_read_reg(dc->ctx,
-+ mmDENTIST_DISPCLK_CNTL);
-+
-+ /* Convert DENTIST_DPREFCLK_WDIVIDERto actual divider*/
-+ target_div = dal_divider_range_get_divider(
-+ divider_ranges,
-+ DIVIDER_RANGE_MAX,
-+ get_reg_field_value(dispclk_cntl_value,
-+ DENTIST_DISPCLK_CNTL,
-+ DENTIST_DPREFCLK_WDIVIDER));
-+
-+
-+ if (target_div != INVALID_DIVIDER) {
-+ /* Calculate the current DFS clock, in kHz.*/
-+ dp_ref_clk_khz = (DIVIDER_RANGE_SCALE_FACTOR
-+ * disp_clk->dentist_vco_freq_khz) / target_div;
-+ }
-+
-+ /* SW will adjust DP REF Clock average value for all purposes
-+ * (DP DTO / DP Audio DTO and DP GTC)
-+ if clock is spread for all cases:
-+ -if SS enabled on DP Ref clock and HW de-spreading enabled with SW
-+ calculations for DS_INCR/DS_MODULO (this is planned to be default case)
-+ -if SS enabled on DP Ref clock and HW de-spreading enabled with HW
-+ calculations (not planned to be used, but average clock should still
-+ be valid)
-+ -if SS enabled on DP Ref clock and HW de-spreading disabled
-+ (should not be case with CIK) then SW should program all rates
-+ generated according to average value (case as with previous ASICs)
-+ */
-+ if ((disp_clk->ss_on_gpu_pll) && (disp_clk->gpu_pll_ss_divider != 0)) {
-+ struct fixed32_32 ss_percentage = dal_fixed32_32_div_int(
-+ dal_fixed32_32_from_fraction(
-+ disp_clk->gpu_pll_ss_percentage,
-+ disp_clk->gpu_pll_ss_divider), 200);
-+ struct fixed32_32 adj_dp_ref_clk_khz;
-+
-+ ss_percentage = dal_fixed32_32_sub(dal_fixed32_32_one,
-+ ss_percentage);
-+ adj_dp_ref_clk_khz =
-+ dal_fixed32_32_mul_int(
-+ ss_percentage,
-+ dp_ref_clk_khz);
-+ dp_ref_clk_khz = dal_fixed32_32_floor(adj_dp_ref_clk_khz);
-+ }
-+
-+ return dp_ref_clk_khz;
-+}
-+
-+
-+static void destroy(struct display_clock **base)
-+{
-+ struct display_clock_dce110 *dc110;
-+
-+ dc110 = DCLCK110_FROM_BASE(*base);
-+
-+ dc_service_free((*base)->ctx, dc110);
-+
-+ *base = NULL;
-+}
-+
-+static uint32_t get_validation_clock(struct display_clock *dc)
-+{
-+ uint32_t clk = 0;
-+ struct display_clock_dce110 *disp_clk = DCLCK110_FROM_BASE(dc);
-+
-+ switch (disp_clk->max_clks_state) {
-+ case CLOCKS_STATE_ULTRA_LOW:
-+ /*Currently not supported, it has 0 in table entry*/
-+ case CLOCKS_STATE_LOW:
-+ clk = max_clks_by_state[CLOCKS_STATE_LOW].
-+ display_clk_khz;
-+ break;
-+
-+ case CLOCKS_STATE_NOMINAL:
-+ clk = max_clks_by_state[CLOCKS_STATE_NOMINAL].
-+ display_clk_khz;
-+ break;
-+
-+ case CLOCKS_STATE_PERFORMANCE:
-+ clk = max_clks_by_state[CLOCKS_STATE_PERFORMANCE].
-+ display_clk_khz;
-+ break;
-+
-+ case CLOCKS_STATE_INVALID:
-+ default:
-+ /*Invalid Clocks State*/
-+ dal_logger_write(dc->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Invalid clock state");
-+ /* just return the display engine clock for
-+ * lowest supported state*/
-+ clk = max_clks_by_state[CLOCKS_STATE_LOW].
-+ display_clk_khz;
-+ break;
-+ }
-+ return clk;
-+}
-+
-+static struct fixed32_32 get_deep_color_factor(struct min_clock_params *params)
-+{
-+ /* DeepColorFactor = IF (HDMI = True, bpp / 24, 1)*/
-+ struct fixed32_32 deep_color_factor = dal_fixed32_32_from_int(1);
-+
-+ if (params->signal_type != SIGNAL_TYPE_HDMI_TYPE_A)
-+ return deep_color_factor;
-+
-+ switch (params->deep_color_depth) {
-+ case COLOR_DEPTH_101010:
-+ /*deep color ratio for 30bpp is 30/24 = 1.25*/
-+ deep_color_factor = dal_fixed32_32_from_fraction(30, 24);
-+ break;
-+
-+ case COLOR_DEPTH_121212:
-+ /* deep color ratio for 36bpp is 36/24 = 1.5*/
-+ deep_color_factor = dal_fixed32_32_from_fraction(36, 24);
-+ break;
-+
-+ case COLOR_DEPTH_161616:
-+ /* deep color ratio for 48bpp is 48/24 = 2.0 */
-+ deep_color_factor = dal_fixed32_32_from_fraction(48, 24);
-+ break;
-+ default:
-+ break;
-+ }
-+ return deep_color_factor;
-+}
-+
-+static struct fixed32_32 get_scaler_efficiency(
-+ struct dc_context *ctx,
-+ struct min_clock_params *params)
-+{
-+ struct fixed32_32 scaler_efficiency = dal_fixed32_32_from_int(3);
-+
-+ if (params->scaler_efficiency == V_SCALER_EFFICIENCY_LB18BPP) {
-+ scaler_efficiency =
-+ dal_fixed32_32_add(
-+ dal_fixed32_32_from_fraction(35555, 10000),
-+ dal_fixed32_32_from_fraction(
-+ 55556,
-+ 100000 * 10000));
-+ } else if (params->scaler_efficiency == V_SCALER_EFFICIENCY_LB24BPP) {
-+ scaler_efficiency =
-+ dal_fixed32_32_add(
-+ dal_fixed32_32_from_fraction(34285, 10000),
-+ dal_fixed32_32_from_fraction(
-+ 71429,
-+ 100000 * 10000));
-+ } else if (params->scaler_efficiency == V_SCALER_EFFICIENCY_LB30BPP)
-+ scaler_efficiency = dal_fixed32_32_from_fraction(32, 10);
-+
-+ return scaler_efficiency;
-+}
-+
-+static struct fixed32_32 get_lb_lines_in_per_line_out(
-+ struct min_clock_params *params,
-+ struct fixed32_32 v_scale_ratio)
-+{
-+ struct fixed32_32 two = dal_fixed32_32_from_int(2);
-+ struct fixed32_32 four = dal_fixed32_32_from_int(4);
-+ struct fixed32_32 f4_to_3 = dal_fixed32_32_from_fraction(4, 3);
-+ struct fixed32_32 f6_to_4 = dal_fixed32_32_from_fraction(6, 4);
-+
-+ if (params->line_buffer_prefetch_enabled)
-+ return dal_fixed32_32_max(v_scale_ratio, dal_fixed32_32_one);
-+ else if (dal_fixed32_32_le(v_scale_ratio, dal_fixed32_32_one))
-+ return dal_fixed32_32_one;
-+ else if (dal_fixed32_32_le(v_scale_ratio, f4_to_3))
-+ return f4_to_3;
-+ else if (dal_fixed32_32_le(v_scale_ratio, f6_to_4))
-+ return f6_to_4;
-+ else if (dal_fixed32_32_le(v_scale_ratio, two))
-+ return two;
-+ else if (dal_fixed32_32_le(v_scale_ratio, dal_fixed32_32_from_int(3)))
-+ return four;
-+ else
-+ return dal_fixed32_32_zero;
-+}
-+
-+static uint32_t get_actual_required_display_clk(
-+ struct display_clock_dce110 *disp_clk,
-+ uint32_t target_clk_khz)
-+{
-+ uint32_t disp_clk_khz = target_clk_khz;
-+ uint32_t div = INVALID_DIVIDER;
-+ uint32_t did = INVALID_DID;
-+ uint32_t scaled_vco =
-+ disp_clk->dentist_vco_freq_khz * DIVIDER_RANGE_SCALE_FACTOR;
-+
-+ ASSERT_CRITICAL(!!disp_clk_khz);
-+
-+ if (disp_clk_khz)
-+ div = scaled_vco / disp_clk_khz;
-+
-+ did = dal_divider_range_get_did(divider_ranges, DIVIDER_RANGE_MAX, div);
-+
-+ if (did != INVALID_DID) {
-+ div = dal_divider_range_get_divider(
-+ divider_ranges, DIVIDER_RANGE_MAX, did);
-+
-+ if ((div != INVALID_DIVIDER) &&
-+ (did > DIVIDER_RANGE_01_BASE_DIVIDER_ID))
-+ if (disp_clk_khz > (scaled_vco / div))
-+ div = dal_divider_range_get_divider(
-+ divider_ranges, DIVIDER_RANGE_MAX,
-+ did - 1);
-+
-+ if (div != INVALID_DIVIDER)
-+ disp_clk_khz = scaled_vco / div;
-+
-+ }
-+ /* We need to add 10KHz to this value because the accuracy in VBIOS is
-+ in 10KHz units. So we need to always round the last digit up in order
-+ to reach the next div level.*/
-+ return disp_clk_khz + 10;
-+}
-+
-+static uint32_t calc_single_display_min_clks(
-+ struct display_clock *base,
-+ struct min_clock_params *params,
-+ bool set_clk)
-+{
-+ struct fixed32_32 h_scale_ratio = dal_fixed32_32_one;
-+ struct fixed32_32 v_scale_ratio = dal_fixed32_32_one;
-+ uint32_t pix_clk_khz = 0;
-+ uint32_t lb_source_width = 0;
-+ struct fixed32_32 deep_color_factor;
-+ struct fixed32_32 scaler_efficiency;
-+ struct fixed32_32 v_filter_init;
-+ uint32_t v_filter_init_trunc;
-+ uint32_t num_lines_at_frame_start = 3;
-+ struct fixed32_32 v_filter_init_ceil;
-+ struct fixed32_32 lines_per_lines_out_at_frame_start;
-+ struct fixed32_32 lb_lines_in_per_line_out; /* in middle of the frame*/
-+ uint32_t src_wdth_rnd_to_chunks;
-+ struct fixed32_32 scaling_coeff;
-+ struct fixed32_32 h_blank_granularity_factor =
-+ dal_fixed32_32_one;
-+ struct fixed32_32 fx_disp_clk_mhz;
-+ struct fixed32_32 line_time;
-+ struct fixed32_32 disp_pipe_pix_throughput;
-+ struct fixed32_32 fx_alt_disp_clk_mhz;
-+ uint32_t disp_clk_khz;
-+ uint32_t alt_disp_clk_khz;
-+ struct display_clock_dce110 *disp_clk_110 = DCLCK110_FROM_BASE(base);
-+ uint32_t max_clk_khz = get_validation_clock(base);
-+ bool panning_allowed = false; /* TODO: receive this value from AS */
-+
-+ if (params == NULL) {
-+ dal_logger_write(base->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Invalid input parameter in %s",
-+ __func__);
-+ return 0;
-+ }
-+
-+ deep_color_factor = get_deep_color_factor(params);
-+ scaler_efficiency = get_scaler_efficiency(base->ctx, params);
-+ pix_clk_khz = params->requested_pixel_clock;
-+ lb_source_width = params->source_view.width;
-+
-+ if (0 != params->dest_view.height && 0 != params->dest_view.width) {
-+
-+ h_scale_ratio = dal_fixed32_32_from_fraction(
-+ params->source_view.width,
-+ params->dest_view.width);
-+ v_scale_ratio = dal_fixed32_32_from_fraction(
-+ params->source_view.height,
-+ params->dest_view.height);
-+ } else {
-+ dal_logger_write(base->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Destination height or width is 0!\n");
-+ }
-+
-+ v_filter_init =
-+ dal_fixed32_32_add(
-+ v_scale_ratio,
-+ dal_fixed32_32_add_int(
-+ dal_fixed32_32_div_int(
-+ dal_fixed32_32_mul_int(
-+ v_scale_ratio,
-+ params->timing_info.INTERLACED),
-+ 2),
-+ params->scaling_info.v_taps + 1));
-+ v_filter_init = dal_fixed32_32_div_int(v_filter_init, 2);
-+
-+ v_filter_init_trunc = dal_fixed32_32_floor(v_filter_init);
-+
-+ v_filter_init_ceil = dal_fixed32_32_from_fraction(
-+ v_filter_init_trunc, 2);
-+ v_filter_init_ceil = dal_fixed32_32_from_int(
-+ dal_fixed32_32_ceil(v_filter_init_ceil));
-+ v_filter_init_ceil = dal_fixed32_32_mul_int(v_filter_init_ceil, 2);
-+
-+ lines_per_lines_out_at_frame_start =
-+ dal_fixed32_32_div_int(v_filter_init_ceil,
-+ num_lines_at_frame_start);
-+ lb_lines_in_per_line_out =
-+ get_lb_lines_in_per_line_out(params, v_scale_ratio);
-+
-+ if (panning_allowed)
-+ src_wdth_rnd_to_chunks =
-+ ((lb_source_width - 1) / 128) * 128 + 256;
-+ else
-+ src_wdth_rnd_to_chunks =
-+ ((lb_source_width + 127) / 128) * 128;
-+
-+ scaling_coeff =
-+ dal_fixed32_32_div(
-+ dal_fixed32_32_from_int(params->scaling_info.v_taps),
-+ scaler_efficiency);
-+
-+ if (dal_fixed32_32_le(h_scale_ratio, dal_fixed32_32_one))
-+ scaling_coeff = dal_fixed32_32_max(
-+ dal_fixed32_32_from_int(
-+ dal_fixed32_32_ceil(
-+ dal_fixed32_32_from_fraction(
-+ params->scaling_info.h_taps,
-+ 4))),
-+ dal_fixed32_32_max(
-+ dal_fixed32_32_mul(
-+ scaling_coeff,
-+ h_scale_ratio),
-+ dal_fixed32_32_one));
-+
-+ if (!params->line_buffer_prefetch_enabled &&
-+ dal_fixed32_32_floor(lb_lines_in_per_line_out) != 2 &&
-+ dal_fixed32_32_floor(lb_lines_in_per_line_out) != 4) {
-+ uint32_t line_total_pixel =
-+ params->timing_info.h_total + lb_source_width - 256;
-+ h_blank_granularity_factor = dal_fixed32_32_div(
-+ dal_fixed32_32_from_int(params->timing_info.h_total),
-+ dal_fixed32_32_div(
-+ dal_fixed32_32_from_fraction(
-+ line_total_pixel, 2),
-+ h_scale_ratio));
-+ }
-+
-+ /* Calculate display clock with ramping. Ramping factor is 1.1*/
-+ fx_disp_clk_mhz =
-+ dal_fixed32_32_div_int(
-+ dal_fixed32_32_mul_int(scaling_coeff, 11),
-+ 10);
-+ line_time = dal_fixed32_32_from_fraction(
-+ params->timing_info.h_total * 1000, pix_clk_khz);
-+
-+ disp_pipe_pix_throughput = dal_fixed32_32_mul(
-+ lb_lines_in_per_line_out, h_blank_granularity_factor);
-+ disp_pipe_pix_throughput = dal_fixed32_32_max(
-+ disp_pipe_pix_throughput,
-+ lines_per_lines_out_at_frame_start);
-+ disp_pipe_pix_throughput = dal_fixed32_32_div(dal_fixed32_32_mul_int(
-+ disp_pipe_pix_throughput, src_wdth_rnd_to_chunks),
-+ line_time);
-+
-+ if (0 != params->timing_info.h_total) {
-+ fx_disp_clk_mhz =
-+ dal_fixed32_32_max(
-+ dal_fixed32_32_div_int(
-+ dal_fixed32_32_mul_int(
-+ scaling_coeff, pix_clk_khz),
-+ 1000),
-+ disp_pipe_pix_throughput);
-+ fx_disp_clk_mhz =
-+ dal_fixed32_32_mul(
-+ fx_disp_clk_mhz,
-+ dal_fixed32_32_from_fraction(11, 10));
-+ }
-+
-+ fx_disp_clk_mhz = dal_fixed32_32_max(fx_disp_clk_mhz,
-+ dal_fixed32_32_mul(deep_color_factor,
-+ dal_fixed32_32_from_fraction(11, 10)));
-+
-+ /* Calculate display clock without ramping */
-+ fx_alt_disp_clk_mhz = scaling_coeff;
-+
-+ if (0 != params->timing_info.h_total) {
-+ fx_alt_disp_clk_mhz = dal_fixed32_32_max(
-+ dal_fixed32_32_div_int(dal_fixed32_32_mul_int(
-+ scaling_coeff, pix_clk_khz),
-+ 1000),
-+ dal_fixed32_32_div_int(dal_fixed32_32_mul_int(
-+ disp_pipe_pix_throughput, 105),
-+ 100));
-+ }
-+
-+ if (set_clk && disp_clk_110->ss_on_gpu_pll &&
-+ disp_clk_110->gpu_pll_ss_divider)
-+ fx_alt_disp_clk_mhz = dal_fixed32_32_mul(fx_alt_disp_clk_mhz,
-+ dal_fixed32_32_add_int(
-+ dal_fixed32_32_div_int(
-+ dal_fixed32_32_div_int(
-+ dal_fixed32_32_from_fraction(
-+ disp_clk_110->gpu_pll_ss_percentage,
-+ disp_clk_110->gpu_pll_ss_divider), 100),
-+ 2),
-+ 1));
-+
-+ /* convert to integer */
-+ disp_clk_khz = dal_fixed32_32_round(
-+ dal_fixed32_32_mul_int(fx_disp_clk_mhz, 1000));
-+ alt_disp_clk_khz = dal_fixed32_32_round(
-+ dal_fixed32_32_mul_int(fx_alt_disp_clk_mhz, 1000));
-+
-+ if ((disp_clk_khz > max_clk_khz) && (alt_disp_clk_khz <= max_clk_khz))
-+ disp_clk_khz = alt_disp_clk_khz;
-+
-+ if (set_clk) { /* only compensate clock if we are going to set it.*/
-+ disp_clk_khz = get_actual_required_display_clk(
-+ disp_clk_110, disp_clk_khz);
-+ }
-+
-+ disp_clk_khz = disp_clk_khz > max_clk_khz ? max_clk_khz : disp_clk_khz;
-+
-+ return disp_clk_khz;
-+}
-+
-+static uint32_t calculate_min_clock(
-+ struct display_clock *base,
-+ uint32_t path_num,
-+ struct min_clock_params *params)
-+{
-+ uint32_t i;
-+ uint32_t validation_clk_khz =
-+ get_validation_clock(base);
-+ uint32_t min_clk_khz = validation_clk_khz;
-+ uint32_t max_clk_khz = 0;
-+ struct display_clock_dce110 *dc = DCLCK110_FROM_BASE(base);
-+
-+ if (dc->use_max_disp_clk)
-+ return min_clk_khz;
-+
-+ if (params != NULL) {
-+ uint32_t disp_clk_khz = 0;
-+
-+ for (i = 0; i < path_num; ++i) {
-+
-+ disp_clk_khz = calc_single_display_min_clks(
-+ base, params, true);
-+
-+ /* update the max required clock found*/
-+ if (disp_clk_khz > max_clk_khz)
-+ max_clk_khz = disp_clk_khz;
-+
-+ params++;
-+ }
-+ }
-+
-+ min_clk_khz = max_clk_khz;
-+
-+ if (min_clk_khz > validation_clk_khz)
-+ min_clk_khz = validation_clk_khz;
-+ else if (min_clk_khz < base->min_display_clk_threshold_khz)
-+ min_clk_khz = base->min_display_clk_threshold_khz;
-+
-+ if (dc->use_max_disp_clk)
-+ min_clk_khz = get_validation_clock(base);
-+
-+ return min_clk_khz;
-+}
-+
-+static bool display_clock_integrated_info_construct(
-+ struct display_clock_dce110 *disp_clk,
-+ struct adapter_service *as)
-+{
-+ struct integrated_info info;
-+ uint32_t i;
-+
-+ struct display_clock *base = &disp_clk->disp_clk_base;
-+
-+ if (!dal_adapter_service_get_integrated_info(as, &info))
-+ return false;
-+
-+ disp_clk->dentist_vco_freq_khz = info.dentist_vco_freq;
-+ if (disp_clk->dentist_vco_freq_khz == 0)
-+ disp_clk->dentist_vco_freq_khz = 3600000;
-+
-+ base->min_display_clk_threshold_khz =
-+ disp_clk->dentist_vco_freq_khz / 64;
-+
-+ /*update the maximum display clock for each power state*/
-+ for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
-+ enum clocks_state clk_state = CLOCKS_STATE_INVALID;
-+
-+ switch (i) {
-+ case 0:
-+ clk_state = CLOCKS_STATE_ULTRA_LOW;
-+ break;
-+
-+ case 1:
-+ clk_state = CLOCKS_STATE_LOW;
-+ break;
-+
-+ case 2:
-+ clk_state = CLOCKS_STATE_NOMINAL;
-+ break;
-+
-+ case 3:
-+ clk_state = CLOCKS_STATE_PERFORMANCE;
-+ break;
-+
-+ default:
-+ clk_state = CLOCKS_STATE_INVALID;
-+ break;
-+ }
-+
-+ /*Do not allow bad VBIOS/SBIOS to override with invalid values,
-+ * check for > 100MHz*/
-+ if (info.disp_clk_voltage[i].max_supported_clk >= 100000) {
-+ max_clks_by_state[clk_state].display_clk_khz =
-+ info.disp_clk_voltage[i].max_supported_clk;
-+ }
-+ }
-+ disp_clk->dfs_bypass_enabled =
-+ dal_adapter_service_is_dfs_bypass_enabled(as);
-+ disp_clk->use_max_disp_clk =
-+ dal_adapter_service_is_feature_supported(
-+ FEATURE_USE_MAX_DISPLAY_CLK);
-+
-+ return true;
-+}
-+
-+static uint32_t get_clock(struct display_clock *dc)
-+{
-+ uint32_t disp_clock = get_validation_clock(dc);
-+ uint32_t target_div = INVALID_DIVIDER;
-+ uint32_t addr = mmDENTIST_DISPCLK_CNTL;
-+ uint32_t value = 0;
-+ uint32_t field = 0;
-+ struct display_clock_dce110 *disp_clk = DCLCK110_FROM_BASE(dc);
-+
-+ if (disp_clk->dfs_bypass_enabled && disp_clk->dfs_bypass_disp_clk)
-+ return disp_clk->dfs_bypass_disp_clk;
-+
-+ /* Read the mmDENTIST_DISPCLK_CNTL to get the currently programmed
-+ DID DENTIST_DISPCLK_WDIVIDER.*/
-+ value = dal_read_reg(dc->ctx, addr);
-+ field = get_reg_field_value(
-+ value, DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER);
-+
-+ /* Convert DENTIST_DISPCLK_WDIVIDER to actual divider*/
-+ target_div = dal_divider_range_get_divider(
-+ divider_ranges,
-+ DIVIDER_RANGE_MAX,
-+ field);
-+
-+ if (target_div != INVALID_DIVIDER)
-+ /* Calculate the current DFS clock in KHz.
-+ Should be okay up to 42.9 THz before overflowing.*/
-+ disp_clock = (DIVIDER_RANGE_SCALE_FACTOR
-+ * disp_clk->dentist_vco_freq_khz) / target_div;
-+ return disp_clock;
-+}
-+
-+static enum clocks_state get_required_clocks_state(
-+ struct display_clock *dc,
-+ struct state_dependent_clocks *req_clocks)
-+{
-+ int32_t i;
-+ struct display_clock_dce110 *disp_clk = DCLCK110_FROM_BASE(dc);
-+ enum clocks_state low_req_clk = disp_clk->max_clks_state;
-+
-+ if (!req_clocks) {
-+ /* NULL pointer*/
-+ dal_logger_write(dc->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s: Invalid parameter",
-+ __func__);
-+ return CLOCKS_STATE_INVALID;
-+ }
-+
-+ /* Iterate from highest supported to lowest valid state, and update
-+ * lowest RequiredState with the lowest state that satisfies
-+ * all required clocks
-+ */
-+ for (i = disp_clk->max_clks_state; i >= CLOCKS_STATE_ULTRA_LOW; --i) {
-+ if ((req_clocks->display_clk_khz <=
-+ max_clks_by_state[i].display_clk_khz) &&
-+ (req_clocks->pixel_clk_khz <=
-+ max_clks_by_state[i].pixel_clk_khz))
-+ low_req_clk = i;
-+ }
-+ return low_req_clk;
-+}
-+
-+static void set_clock(
-+ struct display_clock *base,
-+ uint32_t requested_clk_khz)
-+{
-+ struct bp_pixel_clock_parameters pxl_clk_params;
-+ struct display_clock_dce110 *dc = DCLCK110_FROM_BASE(base);
-+ struct bios_parser *bp = dal_adapter_service_get_bios_parser(base->as);
-+
-+ /* Prepare to program display clock*/
-+ dc_service_memset(&pxl_clk_params, 0, sizeof(pxl_clk_params));
-+
-+ pxl_clk_params.target_pixel_clock = requested_clk_khz;
-+ pxl_clk_params.pll_id = base->id;
-+
-+ dal_bios_parser_program_display_engine_pll(bp, &pxl_clk_params);
-+
-+ if (dc->dfs_bypass_enabled) {
-+
-+ /* Cache the fixed display clock*/
-+ dc->dfs_bypass_disp_clk =
-+ pxl_clk_params.dfs_bypass_display_clock;
-+ }
-+
-+ /* from power down, we need mark the clock state as ClocksStateNominal
-+ * from HWReset, so when resume we will call pplib voltage regulator.*/
-+ if (requested_clk_khz == 0)
-+ base->cur_min_clks_state = CLOCKS_STATE_NOMINAL;
-+}
-+
-+static void set_clock_state(
-+ struct display_clock *dc,
-+ struct display_clock_state clk_state)
-+{
-+ struct display_clock_dce110 *disp_clk = DCLCK110_FROM_BASE(dc);
-+
-+ disp_clk->clock_state = clk_state;
-+}
-+
-+static struct display_clock_state get_clock_state(
-+ struct display_clock *dc)
-+{
-+ struct display_clock_dce110 *disp_clk = DCLCK110_FROM_BASE(dc);
-+
-+ return disp_clk->clock_state;
-+}
-+
-+static uint32_t get_dfs_bypass_threshold(struct display_clock *dc)
-+{
-+ return DCE110_DFS_BYPASS_THRESHOLD_KHZ;
-+}
-+
-+static const struct display_clock_funcs funcs = {
-+ .destroy = destroy,
-+ .calculate_min_clock = calculate_min_clock,
-+ .get_clock = get_clock,
-+ .get_clock_state = get_clock_state,
-+ .get_dfs_bypass_threshold = get_dfs_bypass_threshold,
-+ .get_dp_ref_clk_frequency = get_dp_ref_clk_frequency,
-+ .get_min_clocks_state = get_min_clocks_state,
-+ .get_required_clocks_state = get_required_clocks_state,
-+ .get_validation_clock = get_validation_clock,
-+ .set_clock = set_clock,
-+ .set_clock_state = set_clock_state,
-+ .set_dp_ref_clock_source = NULL,
-+ .set_min_clocks_state = set_min_clocks_state,
-+ .store_max_clocks_state = store_max_clocks_state,
-+ .validate = NULL,
-+};
-+
-+static bool dal_display_clock_dce110_construct(
-+ struct display_clock_dce110 *dc110,
-+ struct dc_context *ctx,
-+ struct adapter_service *as)
-+{
-+ struct display_clock *dc_base = &dc110->disp_clk_base;
-+
-+ if (NULL == as)
-+ return false;
-+
-+ if (!dal_display_clock_construct_base(dc_base, ctx, as))
-+ return false;
-+
-+ dc_base->funcs = &funcs;
-+
-+ dc110->dfs_bypass_disp_clk = 0;
-+
-+ if (!display_clock_integrated_info_construct(dc110, as))
-+ dal_logger_write(dc_base->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Cannot obtain VBIOS integrated info\n");
-+
-+ dc110->gpu_pll_ss_percentage = 0;
-+ dc110->gpu_pll_ss_divider = 1000;
-+ dc110->ss_on_gpu_pll = false;
-+
-+ dc_base->id = CLOCK_SOURCE_ID_DFS;
-+/* Initially set max clocks state to nominal. This should be updated by
-+ * via a pplib call to DAL IRI eventually calling a
-+ * DisplayEngineClock_Dce110::StoreMaxClocksState(). This call will come in
-+ * on PPLIB init. This is from DCE5x. in case HW wants to use mixed method.*/
-+ dc110->max_clks_state = CLOCKS_STATE_NOMINAL;
-+
-+ dal_divider_range_construct(
-+ &divider_ranges[DIVIDER_RANGE_01],
-+ DIVIDER_RANGE_01_START,
-+ DIVIDER_RANGE_01_STEP_SIZE,
-+ DIVIDER_RANGE_01_BASE_DIVIDER_ID,
-+ DIVIDER_RANGE_02_BASE_DIVIDER_ID);
-+ dal_divider_range_construct(
-+ &divider_ranges[DIVIDER_RANGE_02],
-+ DIVIDER_RANGE_02_START,
-+ DIVIDER_RANGE_02_STEP_SIZE,
-+ DIVIDER_RANGE_02_BASE_DIVIDER_ID,
-+ DIVIDER_RANGE_03_BASE_DIVIDER_ID);
-+ dal_divider_range_construct(
-+ &divider_ranges[DIVIDER_RANGE_03],
-+ DIVIDER_RANGE_03_START,
-+ DIVIDER_RANGE_03_STEP_SIZE,
-+ DIVIDER_RANGE_03_BASE_DIVIDER_ID,
-+ DIVIDER_RANGE_MAX_DIVIDER_ID);
-+
-+ {
-+ uint32_t ss_info_num =
-+ dal_adapter_service_get_ss_info_num(
-+ as,
-+ AS_SIGNAL_TYPE_GPU_PLL);
-+
-+ if (ss_info_num) {
-+ struct spread_spectrum_info info;
-+ bool result;
-+
-+ dc_service_memset(&info, 0, sizeof(info));
-+
-+ result =
-+ dal_adapter_service_get_ss_info(
-+ as,
-+ AS_SIGNAL_TYPE_GPU_PLL,
-+ 0,
-+ &info);
-+
-+ /* Based on VBIOS, VBIOS will keep entry for GPU PLL SS
-+ * even if SS not enabled and in that case
-+ * SSInfo.spreadSpectrumPercentage !=0 would be sign
-+ * that SS is enabled
-+ */
-+ if (result && info.spread_spectrum_percentage != 0) {
-+ dc110->ss_on_gpu_pll = true;
-+ dc110->gpu_pll_ss_divider =
-+ info.spread_percentage_divider;
-+
-+ if (info.type.CENTER_MODE == 0) {
-+ /* Currently for DP Reference clock we
-+ * need only SS percentage for
-+ * downspread */
-+ dc110->gpu_pll_ss_percentage =
-+ info.spread_spectrum_percentage;
-+ }
-+ }
-+
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+/*****************************************************************************
-+ * public functions
-+ *****************************************************************************/
-+
-+struct display_clock *dal_display_clock_dce110_create(
-+ struct dc_context *ctx,
-+ struct adapter_service *as)
-+{
-+ struct display_clock_dce110 *dc110;
-+
-+ dc110 = dc_service_alloc(ctx, sizeof(struct display_clock_dce110));
-+
-+ if (dc110 == NULL)
-+ return NULL;
-+
-+ if (dal_display_clock_dce110_construct(dc110, ctx, as))
-+ return &dc110->disp_clk_base;
-+
-+ dc_service_free(ctx, dc110);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce110/display_clock_dce110.h b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/display_clock_dce110.h
-new file mode 100644
-index 0000000..0cdc7b5
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/display_clock_dce110.h
-@@ -0,0 +1,53 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef __DAL_DISPLAY_CLOCK_DCE110_H__
-+#define __DAL_DISPLAY_CLOCK_DCE110_H__
-+
-+#include "gpu/display_clock.h"
-+
-+struct display_clock_dce110 {
-+ struct display_clock disp_clk_base;
-+ /* Max display block clocks state*/
-+ enum clocks_state max_clks_state;
-+ bool use_max_disp_clk;
-+ uint32_t dentist_vco_freq_khz;
-+ /* Cache the status of DFS-bypass feature*/
-+ bool dfs_bypass_enabled;
-+ /* GPU PLL SS percentage (if down-spread enabled) */
-+ uint32_t gpu_pll_ss_percentage;
-+ /* GPU PLL SS percentage Divider (100 or 1000) */
-+ uint32_t gpu_pll_ss_divider;
-+ /* Flag for Enabled SS on GPU PLL */
-+ bool ss_on_gpu_pll;
-+ /* Cache the display clock returned by VBIOS if DFS-bypass is enabled.
-+ * This is basically "Crystal Frequency In KHz" (XTALIN) frequency */
-+ uint32_t dfs_bypass_disp_clk;
-+ struct display_clock_state clock_state;
-+};
-+
-+#define DCLCK110_FROM_BASE(dc_base) \
-+ container_of(dc_base, struct display_clock_dce110, disp_clk_base)
-+
-+#endif /* __DAL_DISPLAY_CLOCK_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce110/ext_clock_source_dce110.c b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/ext_clock_source_dce110.c
-new file mode 100644
-index 0000000..7fd5984
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/ext_clock_source_dce110.c
-@@ -0,0 +1,383 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "include/logger_interface.h"
-+#include "include/adapter_service_interface.h"
-+#include "include/fixed32_32.h"
-+
-+#include "ext_clock_source_dce110.h"
-+
-+/**
-+ * In this file ECS stands for External Clock Source.
-+ */
-+
-+#define ECS110_FROM_BASE(clk_src_ptr)\
-+ container_of(\
-+ container_of((clk_src_ptr), struct ext_clock_source, base), \
-+ struct ext_clock_source_dce110, base)
-+
-+#define ECS_WARNING(...) \
-+ dal_logger_write(ctx->logger, LOG_MAJOR_WARNING, \
-+ LOG_MINOR_COMPONENT_GPU, __VA_ARGS__)
-+
-+#define ECS_ERROR(...) \
-+ dal_logger_write(ctx->logger, LOG_MAJOR_ERROR, \
-+ LOG_MINOR_COMPONENT_GPU, __VA_ARGS__)
-+
-+/******************************************************************************
-+ * implementation functions
-+ *****************************************************************************/
-+
-+static uint32_t controller_id_to_index(
-+ struct clock_source *clk_src,
-+ enum controller_id controller_id)
-+{
-+ struct dc_context *ctx = clk_src->ctx;
-+ uint32_t index = 0;
-+
-+ switch (controller_id) {
-+ case CONTROLLER_ID_D0:
-+ index = 0;
-+ break;
-+ case CONTROLLER_ID_D1:
-+ index = 1;
-+ break;
-+ case CONTROLLER_ID_D2:
-+ index = 2;
-+ break;
-+ default:
-+ ECS_ERROR("%s: invalid input controller_id = %d!\n",
-+ __func__, controller_id);
-+ break;
-+ }
-+
-+ return index;
-+}
-+
-+/* Adjust pixel rate by DTO programming (used for DisplayPort) */
-+static bool adjust_dto_pixel_rate(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ uint32_t requested_pix_clk_hz)
-+{
-+ struct ext_clock_source_dce110 *ecs110 =
-+ ECS110_FROM_BASE(clk_src);
-+ struct dc_context *ctx = clk_src->ctx;
-+ uint32_t index;
-+ uint32_t dto_phase_reg;
-+ uint32_t dto_modulo_reg;
-+ uint32_t dto_phase_rnd;
-+ uint32_t addr;
-+ uint32_t value;
-+ struct fixed32_32 dto_phase;
-+
-+ if (NULL == pix_clk_params) {
-+ ECS_WARNING("%s: invalid input!\n", __func__);
-+ return false;
-+ }
-+
-+ index = controller_id_to_index(clk_src, pix_clk_params->controller_id);
-+
-+ addr = ecs110->registers[index].dp_dtox_phase;
-+ dto_phase_reg = dal_read_reg(ctx, addr);
-+
-+ addr = ecs110->registers[index].dp_dtox_modulo;
-+ dto_modulo_reg = dal_read_reg(ctx, addr);
-+
-+ if (!dto_modulo_reg) {
-+ ECS_WARNING("%s: current modulo is zero!\n", __func__);
-+ return false;
-+ }
-+
-+ dto_phase = dal_fixed32_32_from_int(requested_pix_clk_hz);
-+
-+ dto_phase = dal_fixed32_32_mul_int(dto_phase, dto_modulo_reg);
-+
-+ dto_phase = dal_fixed32_32_div_int(dto_phase,
-+ pix_clk_params->dp_ref_clk * 1000);
-+
-+ dto_phase_rnd = dal_fixed32_32_round(dto_phase);
-+
-+ /* Program DTO Phase */
-+ if (dto_phase_reg != dto_phase_rnd) {
-+ /* If HW De-Spreading enabled on DP REF clock and if there will
-+ * be case when Pixel rate > average DP Ref Clock, then need to
-+ * disable de-spread for DP DTO (ATOMBIOS will program MODULO
-+ * for average DP REF clock so no further SW adjustment
-+ * needed) */
-+ if (pix_clk_params->de_spread_params.hw_dso_n_dp_ref_clk) {
-+
-+ addr = ecs110->registers[index].crtcx_pixel_rate_cntl;
-+ value = dal_read_reg(ctx, addr);
-+
-+ if (requested_pix_clk_hz / 1000 >
-+ pix_clk_params->
-+ de_spread_params.avg_dp_ref_clk_khz) {
-+
-+ set_reg_field_value(value, 1,
-+ CRTC0_PIXEL_RATE_CNTL,
-+ DP_DTO0_DS_DISABLE);
-+ } else {
-+ set_reg_field_value(value, 0,
-+ CRTC0_PIXEL_RATE_CNTL,
-+ DP_DTO0_DS_DISABLE);
-+ }
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+
-+ value = 0;
-+ addr = ecs110->registers[index].dp_dtox_phase;
-+
-+ set_reg_field_value(value, dto_phase_rnd,
-+ DP_DTO0_PHASE,
-+ DP_DTO0_PHASE);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+
-+ return true;
-+}
-+
-+/**
-+ * Retrieve Pixel Rate (in Hz) from HW registers already programmed.
-+ */
-+uint32_t retrieve_dp_pixel_rate_from_display_pll(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *params)
-+{
-+ struct dc_context *ctx = clk_src->ctx;
-+
-+ /* TODO: update when DAL2 implements this function. */
-+ DAL_LOGGER_NOT_IMPL(LOG_MINOR_COMPONENT_GPU, "%s\n", __func__);
-+ return 0;
-+}
-+
-+static uint32_t retrieve_dto_pix_rate_hz(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *params)
-+{
-+ struct ext_clock_source_dce110 *ecs110 =
-+ ECS110_FROM_BASE(clk_src);
-+ struct dc_context *ctx = clk_src->ctx;
-+ uint32_t index;
-+ uint32_t dto_phase_reg;
-+ uint32_t dto_modulo_reg;
-+ uint32_t addr;
-+ uint32_t value;
-+ uint32_t pix_rate_hz;
-+ struct fixed32_32 p_clk;
-+
-+ if (params == NULL)
-+ return 0;
-+
-+ if (NULL == params) {
-+ ECS_WARNING("%s: invalid input!\n", __func__);
-+ return false;
-+ }
-+
-+ index = controller_id_to_index(clk_src, params->controller_id);
-+
-+ addr = ecs110->registers[index].crtcx_pixel_rate_cntl;
-+ value = dal_read_reg(ctx, addr);
-+
-+ if (get_reg_field_value(value, CRTC0_PIXEL_RATE_CNTL, DP_DTO0_ENABLE)
-+ == 1) {
-+
-+ addr = ecs110->registers[index].dp_dtox_phase;
-+ dto_phase_reg = dal_read_reg(ctx, addr);
-+
-+ addr = ecs110->registers[index].dp_dtox_modulo;
-+ dto_modulo_reg = dal_read_reg(ctx, addr);
-+
-+ if (!dto_modulo_reg) {
-+ ECS_WARNING("%s: current modulo is zero!\n", __func__);
-+ return 0;
-+ }
-+
-+ /* Calculate pixel clock from DTO Phase & Modulo*/
-+ p_clk = dal_fixed32_32_from_int(params->dp_ref_clk * 1000);
-+
-+ p_clk = dal_fixed32_32_mul_int(p_clk, dto_phase_reg);
-+
-+ p_clk = dal_fixed32_32_div_int(p_clk, dto_modulo_reg);
-+
-+ pix_rate_hz = dal_fixed32_32_round(p_clk);
-+ } else {
-+ pix_rate_hz = retrieve_dp_pixel_rate_from_display_pll(clk_src,
-+ params);
-+ }
-+
-+ return pix_rate_hz;
-+}
-+
-+/******************************************************************************
-+ * create/destroy functions
-+ *****************************************************************************/
-+
-+static void destruct(struct ext_clock_source_dce110 *ecs110)
-+{
-+ struct ext_clock_source *ext_cs = &ecs110->base;
-+ struct clock_source *base = &ext_cs->base;
-+
-+ if (NULL != base->dp_ss_params) {
-+ dc_service_free(base->ctx, base->dp_ss_params);
-+ base->dp_ss_params = NULL;
-+ }
-+
-+ dc_service_free(base->ctx, ecs110->registers);
-+ ecs110->registers = NULL;
-+}
-+
-+
-+static void destroy(struct clock_source **clk_src)
-+{
-+ struct ext_clock_source_dce110 *ecs110;
-+
-+ ecs110 = ECS110_FROM_BASE(*clk_src);
-+
-+ destruct(ecs110);
-+
-+ dc_service_free((*clk_src)->ctx, ecs110);
-+
-+ *clk_src = NULL;
-+}
-+
-+static const struct clock_source_impl funcs = {
-+ .program_pix_clk = dal_ext_clock_source_program_pix_clk,
-+ .adjust_pll_pixel_rate = dal_clock_source_base_adjust_pll_pixel_rate,
-+ .adjust_dto_pixel_rate = adjust_dto_pixel_rate,
-+ .retrieve_pll_pix_rate_hz =
-+ dal_clock_source_base_retrieve_pll_pix_rate_hz,
-+ .get_pix_clk_dividers = dal_ext_clock_source_get_pix_clk_dividers,
-+ .destroy = destroy,
-+ .retrieve_dto_pix_rate_hz = retrieve_dto_pix_rate_hz,
-+ .power_down_pll = dal_ext_clock_source_power_down_pll
-+};
-+
-+static bool construct(
-+ struct ext_clock_source_dce110 *ecs110,
-+ struct clock_source_init_data *clk_src_init_data)
-+{
-+ struct dc_context *ctx = clk_src_init_data->ctx;
-+ struct ext_clock_source *ext_cs = &ecs110->base;
-+ struct clock_source *base = &ext_cs->base;
-+ uint32_t controllers_num;
-+ struct registers *registers;
-+
-+ /* None of the base construct() functions allocates memory.
-+ * That means, in case of error, we don't have to free memory
-+ * allocated by base. */
-+ if (!dal_ext_clock_source_construct(ext_cs, clk_src_init_data))
-+ return false;
-+
-+ base->funcs = &funcs;
-+
-+ base->is_gen_lock_capable = false;
-+ base->dp_ss_params = NULL;
-+ base->dp_ss_params_cnt = 0;
-+
-+ ecs110->registers = NULL;
-+
-+ if (base->clk_src_id != CLOCK_SOURCE_ID_EXTERNAL) {
-+ ECS_ERROR("ECS110:Invalid ClockSourceId = %d!\n",
-+ base->clk_src_id);
-+ return false;
-+ }
-+
-+ controllers_num = dal_adapter_service_get_controllers_num(
-+ base->adapter_service);
-+
-+ if (controllers_num <= 0 || controllers_num > 3) {
-+ ECS_ERROR("ECS110:Invalid number of controllers = %d!\n",
-+ controllers_num);
-+ return false;
-+ }
-+
-+ ecs110->registers = (struct registers *)
-+ (dc_service_alloc(clk_src_init_data->ctx, sizeof(struct registers) * controllers_num));
-+
-+ if (ecs110->registers == NULL) {
-+ ECS_ERROR("ECS110:Failed to allocate 'registers'!\n");
-+ return false;
-+ }
-+
-+ registers = ecs110->registers;
-+
-+ /* Assign register address. No break between cases */
-+ switch (controllers_num) {
-+ case 3:
-+ registers[2].dp_dtox_phase = mmDP_DTO2_PHASE;
-+ registers[2].dp_dtox_modulo = mmDP_DTO2_MODULO;
-+ registers[2].crtcx_pixel_rate_cntl = mmCRTC2_PIXEL_RATE_CNTL;
-+ /* fallthrough */
-+ case 2:
-+ registers[1].dp_dtox_phase = mmDP_DTO1_PHASE;
-+ registers[1].dp_dtox_modulo = mmDP_DTO1_MODULO;
-+ registers[1].crtcx_pixel_rate_cntl = mmCRTC1_PIXEL_RATE_CNTL;
-+ /* fallthrough */
-+ case 1:
-+ registers[0].dp_dtox_phase = mmDP_DTO0_PHASE;
-+ registers[0].dp_dtox_modulo = mmDP_DTO0_MODULO;
-+ registers[0].crtcx_pixel_rate_cntl = mmCRTC0_PIXEL_RATE_CNTL;
-+ break;
-+
-+ default:
-+ /* We can not get here because we checked number of
-+ * controllers already. */
-+ break;
-+ }
-+
-+ dal_clock_source_get_ss_info_from_atombios(
-+ base,
-+ AS_SIGNAL_TYPE_DISPLAY_PORT,
-+ &base->dp_ss_params,
-+ &base->dp_ss_params_cnt);
-+
-+ return true;
-+}
-+
-+
-+struct clock_source *dal_ext_clock_source_dce110_create(
-+ struct clock_source_init_data *clk_src_init_data)
-+{
-+ struct ext_clock_source_dce110 *ecs110;
-+
-+ ecs110 = dc_service_alloc(clk_src_init_data->ctx, sizeof(struct ext_clock_source_dce110));
-+
-+ if (ecs110 == NULL)
-+ return NULL;
-+
-+ if (!construct(ecs110, clk_src_init_data)) {
-+ dc_service_free(clk_src_init_data->ctx, ecs110);
-+ return NULL;
-+ }
-+
-+ return &ecs110->base.base;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce110/ext_clock_source_dce110.h b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/ext_clock_source_dce110.h
-new file mode 100644
-index 0000000..4ea2ae2
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/ext_clock_source_dce110.h
-@@ -0,0 +1,38 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_EXT_CLOCK_SOURCE_DCE110__
-+#define __DAL_EXT_CLOCK_SOURCE_DCE110__
-+
-+#include "../ext_clock_source.h"
-+
-+struct ext_clock_source_dce110 {
-+ struct ext_clock_source base;
-+ struct registers *registers;
-+};
-+
-+struct clock_source *dal_ext_clock_source_dce110_create(
-+ struct clock_source_init_data *clk_src_init_data);
-+
-+#endif /*__DAL_EXT_CLOCK_SOURCE_DCE110__*/
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce110/pll_clock_source_dce110.c b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/pll_clock_source_dce110.c
-new file mode 100644
-index 0000000..d83eea3
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/pll_clock_source_dce110.c
-@@ -0,0 +1,718 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+#include "include/logger_interface.h"
-+#include "include/bios_parser_interface.h"
-+#include "include/adapter_service_interface.h"
-+#include "include/fixed32_32.h"
-+#include "gpu/calc_pll_clock_source.h"
-+#include "gpu/clock_source.h"
-+#include "gpu/pll_clock_source.h"
-+
-+#include "gpu/dce110/pll_clock_source_dce110.h"
-+
-+enum fract_fb_divider_dec_points {
-+ FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM = 6,
-+ FRACT_FB_DIVIDER_DEC_POINTS_NO_DS_NUM = 1,
-+};
-+
-+#define FROM_CLK_SRC(clk_src_ptr)\
-+ container_of(\
-+ container_of((clk_src_ptr), struct pll_clock_source, base), \
-+ struct pll_clock_source_dce110, base)
-+
-+static bool calculate_ss(
-+ struct pll_clock_source_dce110 *clk_src,
-+ struct pll_settings *pll_settings,
-+ const struct spread_spectrum_data *ss_data,
-+ struct delta_sigma_data *ds_data)
-+{
-+ struct fixed32_32 fb_div;
-+ struct fixed32_32 ss_amount;
-+ struct fixed32_32 ss_nslip_amount;
-+ struct fixed32_32 ss_ds_frac_amount;
-+ struct fixed32_32 ss_step_size;
-+ struct fixed32_32 modulation_time;
-+
-+ if (ds_data == NULL)
-+ return false;
-+ if (ss_data == NULL)
-+ return false;
-+ if (ss_data->percentage == 0)
-+ return false;
-+ if (pll_settings == NULL)
-+ return false;
-+
-+
-+ dc_service_memset(ds_data, 0, sizeof(struct delta_sigma_data));
-+
-+
-+
-+ /* compute SS_AMOUNT_FBDIV & SS_AMOUNT_NFRAC_SLIP & SS_AMOUNT_DSFRAC*/
-+ /* 6 decimal point support in fractional feedback divider */
-+ fb_div = dal_fixed32_32_from_fraction(
-+ pll_settings->fract_feedback_divider, 1000000);
-+ fb_div = dal_fixed32_32_add_int(fb_div, pll_settings->feedback_divider);
-+
-+ ds_data->ds_frac_amount = 0;
-+ /*spreadSpectrumPercentage is in the unit of .01%,
-+ * so have to divided by 100 * 100*/
-+ ss_amount = dal_fixed32_32_mul(
-+ fb_div, dal_fixed32_32_from_fraction(ss_data->percentage,
-+ 100 * ss_data->percentage_divider));
-+ ds_data->feedback_amount = dal_fixed32_32_floor(ss_amount);
-+
-+ ss_nslip_amount = dal_fixed32_32_sub(ss_amount,
-+ dal_fixed32_32_from_int(ds_data->feedback_amount));
-+ ss_nslip_amount = dal_fixed32_32_mul_int(ss_nslip_amount, 10);
-+ ds_data->nfrac_amount = dal_fixed32_32_floor(ss_nslip_amount);
-+
-+ ss_ds_frac_amount = dal_fixed32_32_sub(ss_nslip_amount,
-+ dal_fixed32_32_from_int(ds_data->nfrac_amount));
-+ ss_ds_frac_amount = dal_fixed32_32_mul_int(ss_ds_frac_amount, 65536);
-+ ds_data->ds_frac_amount = dal_fixed32_32_floor(ss_ds_frac_amount);
-+
-+ /* compute SS_STEP_SIZE_DSFRAC */
-+ modulation_time = dal_fixed32_32_from_fraction(
-+ pll_settings->reference_freq * 1000,
-+ pll_settings->reference_divider * ss_data->modulation_freq_hz);
-+
-+
-+ if (ss_data->flags.CENTER_SPREAD)
-+ modulation_time = dal_fixed32_32_div_int(modulation_time, 4);
-+ else
-+ modulation_time = dal_fixed32_32_div_int(modulation_time, 2);
-+
-+ ss_step_size = dal_fixed32_32_div(ss_amount, modulation_time);
-+ /* SS_STEP_SIZE_DSFRAC_DEC = Int(SS_STEP_SIZE * 2 ^ 16 * 10)*/
-+ ss_step_size = dal_fixed32_32_mul_int(ss_step_size, 65536 * 10);
-+ ds_data->ds_frac_size = dal_fixed32_32_floor(ss_step_size);
-+
-+ return true;
-+}
-+
-+static bool disable_spread_spectrum(struct pll_clock_source_dce110 *clk_src)
-+{
-+ enum bp_result result;
-+ struct bp_spread_spectrum_parameters bp_ss_params = {0};
-+ struct clock_source *clock_source = NULL;
-+
-+ clock_source = &clk_src->base.base;
-+ bp_ss_params.pll_id = clock_source->clk_src_id;
-+
-+ /*Call ASICControl to process ATOMBIOS Exec table*/
-+ result = dal_bios_parser_enable_spread_spectrum_on_ppll(
-+ clock_source->bios_parser,
-+ &bp_ss_params,
-+ false);
-+
-+ return result == BP_RESULT_OK;
-+}
-+
-+static bool enable_spread_spectrum(
-+ struct pll_clock_source_dce110 *clk_src,
-+ enum signal_type signal, struct pll_settings *pll_settings)
-+{
-+ struct bp_spread_spectrum_parameters bp_params = {0};
-+ struct delta_sigma_data d_s_data;
-+ struct clock_source *clock_source = NULL;
-+ const struct spread_spectrum_data *ss_data = NULL;
-+
-+ clock_source = &clk_src->base.base;
-+ ss_data = dal_clock_source_get_ss_data_entry(
-+ clock_source,
-+ signal,
-+ pll_settings->calculated_pix_clk);
-+
-+/* Pixel clock PLL has been programmed to generate desired pixel clock,
-+ * now enable SS on pixel clock */
-+/* TODO is it OK to return true not doing anything ??*/
-+ if (ss_data != NULL && pll_settings->ss_percentage != 0) {
-+ if (calculate_ss(clk_src, pll_settings, ss_data, &d_s_data)) {
-+ bp_params.ds.feedback_amount =
-+ d_s_data.feedback_amount;
-+ bp_params.ds.nfrac_amount =
-+ d_s_data.nfrac_amount;
-+ bp_params.ds.ds_frac_size = d_s_data.ds_frac_size;
-+ bp_params.ds_frac_amount =
-+ d_s_data.ds_frac_amount;
-+ bp_params.flags.DS_TYPE = 1;
-+ bp_params.pll_id = clock_source->clk_src_id;
-+ bp_params.percentage = ss_data->percentage;
-+ if (ss_data->flags.CENTER_SPREAD)
-+ bp_params.flags.CENTER_SPREAD = 1;
-+ if (ss_data->flags.EXTERNAL_SS)
-+ bp_params.flags.EXTERNAL_SS = 1;
-+
-+ if (BP_RESULT_OK !=
-+ dal_bios_parser_enable_spread_spectrum_on_ppll(
-+ clock_source->bios_parser,
-+ &bp_params,
-+ true))
-+ return false;
-+ } else
-+ return false;
-+ }
-+ return true;
-+}
-+
-+static void program_pixel_clk_resync(
-+ struct pll_clock_source_dce110 *clk_src,
-+ enum signal_type signal_type,
-+ enum dc_color_depth colordepth)
-+{
-+ struct clock_source *clock_source = NULL;
-+ uint32_t value = 0;
-+
-+ clock_source = &clk_src->base.base;
-+
-+ value = dal_read_reg(
-+ clock_source->ctx,
-+ clk_src->pixclkx_resync_cntl);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ PIXCLK1_RESYNC_CNTL,
-+ DCCG_DEEP_COLOR_CNTL1);
-+
-+ /*
-+ 24 bit mode: TMDS clock = 1.0 x pixel clock (1:1)
-+ 30 bit mode: TMDS clock = 1.25 x pixel clock (5:4)
-+ 36 bit mode: TMDS clock = 1.5 x pixel clock (3:2)
-+ 48 bit mode: TMDS clock = 2 x pixel clock (2:1)
-+ */
-+ if (signal_type != SIGNAL_TYPE_HDMI_TYPE_A)
-+ return;
-+
-+ switch (colordepth) {
-+ case COLOR_DEPTH_888:
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ PIXCLK1_RESYNC_CNTL,
-+ DCCG_DEEP_COLOR_CNTL1);
-+ break;
-+ case COLOR_DEPTH_101010:
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ PIXCLK1_RESYNC_CNTL,
-+ DCCG_DEEP_COLOR_CNTL1);
-+ break;
-+ case COLOR_DEPTH_121212:
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ PIXCLK1_RESYNC_CNTL,
-+ DCCG_DEEP_COLOR_CNTL1);
-+ break;
-+ case COLOR_DEPTH_161616:
-+ set_reg_field_value(
-+ value,
-+ 3,
-+ PIXCLK1_RESYNC_CNTL,
-+ DCCG_DEEP_COLOR_CNTL1);
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ dal_write_reg(
-+ clock_source->ctx,
-+ clk_src->pixclkx_resync_cntl,
-+ value);
-+}
-+
-+static bool program_pix_clk(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings)
-+{
-+ struct pll_clock_source_dce110 *pll_clk_src_dce110 =
-+ FROM_CLK_SRC(clk_src);
-+ struct bp_pixel_clock_parameters bp_pc_params = {0};
-+
-+ /* First disable SS
-+ * ATOMBIOS will enable by default SS on PLL for DP,
-+ * do not disable it here
-+ */
-+ if (!dc_is_dp_signal(pix_clk_params->signal_type))
-+ disable_spread_spectrum(pll_clk_src_dce110);
-+
-+ /*ATOMBIOS expects pixel rate adjusted by deep color ratio)*/
-+ bp_pc_params.controller_id = pix_clk_params->controller_id;
-+ bp_pc_params.pll_id = clk_src->clk_src_id;
-+ bp_pc_params.target_pixel_clock =
-+ pll_settings->actual_pix_clk;
-+ bp_pc_params.reference_divider = pll_settings->reference_divider;
-+ bp_pc_params.feedback_divider = pll_settings->feedback_divider;
-+ bp_pc_params.fractional_feedback_divider =
-+ pll_settings->fract_feedback_divider;
-+ bp_pc_params.pixel_clock_post_divider =
-+ pll_settings->pix_clk_post_divider;
-+ bp_pc_params.encoder_object_id = pix_clk_params->encoder_object_id;
-+ bp_pc_params.signal_type = pix_clk_params->signal_type;
-+ bp_pc_params.dvo_config = pix_clk_params->dvo_cfg;
-+ bp_pc_params.flags.SET_EXTERNAL_REF_DIV_SRC =
-+ pll_settings->use_external_clk;
-+
-+ if (dal_bios_parser_set_pixel_clock(clk_src->bios_parser,
-+ &bp_pc_params) != BP_RESULT_OK)
-+ return false;
-+
-+/* Enable SS
-+ * ATOMBIOS will enable by default SS for DP on PLL ( DP ID clock),
-+ * based on HW display PLL team, SS control settings should be programmed
-+ * during PLL Reset, but they do not have effect
-+ * until SS_EN is asserted.*/
-+ if (pix_clk_params->flags.ENABLE_SS && !dc_is_dp_signal(
-+ pix_clk_params->signal_type))
-+ if (!enable_spread_spectrum(pll_clk_src_dce110,
-+ pix_clk_params->signal_type,
-+ pll_settings))
-+ return false;
-+
-+/* Resync deep color DTO */
-+ program_pixel_clk_resync(pll_clk_src_dce110,
-+ pix_clk_params->signal_type,
-+ pix_clk_params->color_depth);
-+
-+ return true;
-+}
-+
-+static void ss_info_from_atombios_destroy(
-+ struct pll_clock_source_dce110 *clk_src)
-+{
-+ struct clock_source *cs = &clk_src->base.base;
-+
-+ if (NULL != cs->ep_ss_params) {
-+ dc_service_free(cs->ctx, cs->ep_ss_params);
-+ cs->ep_ss_params = NULL;
-+ }
-+
-+ if (NULL != cs->dp_ss_params) {
-+ dc_service_free(cs->ctx, cs->dp_ss_params);
-+ cs->dp_ss_params = NULL;
-+ }
-+
-+ if (NULL != cs->hdmi_ss_params) {
-+ dc_service_free(cs->ctx, cs->hdmi_ss_params);
-+ cs->hdmi_ss_params = NULL;
-+ }
-+
-+ if (NULL != cs->dvi_ss_params) {
-+ dc_service_free(cs->ctx, cs->dvi_ss_params);
-+ cs->dvi_ss_params = NULL;
-+ }
-+}
-+
-+static void destruct(
-+ struct pll_clock_source_dce110 *pll_cs)
-+{
-+ ss_info_from_atombios_destroy(pll_cs);
-+
-+ if (NULL != pll_cs->registers) {
-+ dc_service_free(pll_cs->base.base.ctx, pll_cs->registers);
-+ pll_cs->registers = NULL;
-+ }
-+}
-+
-+static void destroy(struct clock_source **clk_src)
-+{
-+ struct pll_clock_source_dce110 *pll_clk_src;
-+
-+ pll_clk_src = FROM_CLK_SRC(*clk_src);
-+
-+ destruct(pll_clk_src);
-+ dc_service_free((*clk_src)->ctx, pll_clk_src);
-+
-+ *clk_src = NULL;
-+}
-+
-+/**
-+ * Calculate PLL Dividers for given Clock Value.
-+ * First will call VBIOS Adjust Exec table to check if requested Pixel clock
-+ * will be Adjusted based on usage.
-+ * Then it will calculate PLL Dividers for this Adjusted clock using preferred
-+ * method (Maximum VCO frequency).
-+ *
-+ * \return
-+ * Calculation error in units of 0.01%
-+ */
-+static uint32_t get_pix_clk_dividers(
-+ struct clock_source *cs,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings)
-+{
-+ struct pll_clock_source_dce110 *pll_cs_110 = FROM_CLK_SRC(cs);
-+ struct pll_clock_source *pll_base = &pll_cs_110->base;
-+ uint32_t pll_calc_error = MAX_PLL_CALC_ERROR;
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+ uint32_t field = 0;
-+
-+ if (pix_clk_params == NULL || pll_settings == NULL
-+ || pix_clk_params->requested_pix_clk == 0) {
-+ dal_logger_write(cs->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s: Invalid parameters!!\n", __func__);
-+ return pll_calc_error;
-+ }
-+
-+ dc_service_memset(pll_settings, 0, sizeof(*pll_settings));
-+
-+ /* Check if reference clock is external (not pcie/xtalin)
-+ * HW Dce80 spec:
-+ * 00 - PCIE_REFCLK, 01 - XTALIN, 02 - GENERICA, 03 - GENERICB
-+ * 04 - HSYNCA, 05 - GENLK_CLK, 06 - PCIE_REFCLK, 07 - DVOCLK0 */
-+ addr = pll_cs_110->pxpll_cntl;
-+ value = dal_read_reg(cs->ctx, addr);
-+ field = get_reg_field_value(value, PLL_CNTL, PLL_REF_DIV_SRC);
-+ pll_settings->use_external_clk = (field > 1);
-+
-+ /* VBIOS by default enables DP SS (spread on IDCLK) for DCE 8.0 always
-+ * (we do not care any more from SI for some older DP Sink which
-+ * does not report SS support, no known issues) */
-+ if ((pix_clk_params->flags.ENABLE_SS) ||
-+ (dc_is_dp_signal(pix_clk_params->signal_type))) {
-+
-+ const struct spread_spectrum_data *ss_data =
-+ dal_clock_source_get_ss_data_entry(
-+ cs,
-+ pix_clk_params->signal_type,
-+ pll_settings->adjusted_pix_clk);
-+
-+ if (NULL != ss_data)
-+ pll_settings->ss_percentage = ss_data->percentage;
-+ }
-+
-+ /* Check VBIOS AdjustPixelClock Exec table */
-+ if (!dal_pll_clock_source_adjust_pix_clk(pll_base,
-+ pix_clk_params, pll_settings)) {
-+ /* Should never happen, ASSERT and fill up values to be able
-+ * to continue. */
-+ dal_logger_write(cs->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s: Failed to adjust pixel clock!!", __func__);
-+ pll_settings->actual_pix_clk =
-+ pix_clk_params->requested_pix_clk;
-+ pll_settings->adjusted_pix_clk =
-+ pix_clk_params->requested_pix_clk;
-+
-+ if (dc_is_dp_signal(pix_clk_params->signal_type))
-+ pll_settings->adjusted_pix_clk = 100000;
-+ }
-+
-+ /* Calculate Dividers */
-+ if (pix_clk_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A)
-+ /*Calculate Dividers by HDMI object, no SS case or SS case */
-+ pll_calc_error =
-+ dal_clock_source_calculate_pixel_clock_pll_dividers(
-+ &pll_cs_110->calc_pll_clock_source_hdmi,
-+ pll_settings);
-+ else
-+ /*Calculate Dividers by default object, no SS case or SS case */
-+ pll_calc_error =
-+ dal_clock_source_calculate_pixel_clock_pll_dividers(
-+ &pll_cs_110->calc_pll_clock_source,
-+ pll_settings);
-+
-+ return pll_calc_error;
-+}
-+
-+static const struct clock_source_impl funcs = {
-+ .program_pix_clk = program_pix_clk,
-+ .adjust_pll_pixel_rate = NULL,
-+ .adjust_dto_pixel_rate = NULL,
-+ .retrieve_pll_pix_rate_hz = NULL,
-+ .get_pix_clk_dividers = get_pix_clk_dividers,
-+ .destroy = destroy,
-+ .retrieve_dto_pix_rate_hz = NULL,
-+ .power_down_pll = dal_pll_clock_source_power_down_pll,
-+};
-+
-+static void ss_info_from_atombios_create(
-+ struct pll_clock_source_dce110 *clk_src)
-+{
-+ struct clock_source *base = &clk_src->base.base;
-+
-+ dal_clock_source_get_ss_info_from_atombios(
-+ base,
-+ AS_SIGNAL_TYPE_DISPLAY_PORT,
-+ &base->dp_ss_params,
-+ &base->dp_ss_params_cnt);
-+ dal_clock_source_get_ss_info_from_atombios(
-+ base,
-+ AS_SIGNAL_TYPE_LVDS,
-+ &base->ep_ss_params,
-+ &base->ep_ss_params_cnt);
-+ dal_clock_source_get_ss_info_from_atombios(
-+ base,
-+ AS_SIGNAL_TYPE_HDMI,
-+ &base->hdmi_ss_params,
-+ &base->hdmi_ss_params_cnt);
-+ dal_clock_source_get_ss_info_from_atombios(
-+ base,
-+ AS_SIGNAL_TYPE_DVI,
-+ &base->dvi_ss_params,
-+ &base->dvi_ss_params_cnt);
-+}
-+
-+
-+static bool construct(
-+ struct pll_clock_source_dce110 *pll_cs_dce110,
-+ struct clock_source_init_data *clk_src_init_data)
-+{
-+ uint32_t controllers_num = 1;
-+
-+/* structure normally used with PLL ranges from ATOMBIOS; DS on by default */
-+ struct calc_pll_clock_source_init_data calc_pll_cs_init_data = {
-+ dal_adapter_service_get_bios_parser(clk_src_init_data->as),
-+ 1, /* minPixelClockPLLPostDivider */
-+ PLL_POST_DIV__PLL_POST_DIV_PIXCLK_MASK,
-+ /* maxPixelClockPLLPostDivider*/
-+ 1,/* minPLLRefDivider*/
-+ PLL_REF_DIV__PLL_REF_DIV_MASK,/* maxPLLRefDivider*/
-+ 0,
-+/* when 0 use minInputPxlClkPLLFrequencyInKHz from firmwareInfo*/
-+ 0,
-+/* when 0 use maxInputPxlClkPLLFrequencyInKHz from firmwareInfo*/
-+ FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM,
-+/*numberOfFractFBDividerDecimalPoints*/
-+ FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM,
-+/*number of decimal point to round off for fractional feedback divider value*/
-+ clk_src_init_data->ctx
-+ };
-+/*structure for HDMI, no SS or SS% <= 0.06% for 27 MHz Ref clock */
-+ struct calc_pll_clock_source_init_data calc_pll_cs_init_data_hdmi = {
-+ dal_adapter_service_get_bios_parser(clk_src_init_data->as),
-+ 1, /* minPixelClockPLLPostDivider */
-+ PLL_POST_DIV__PLL_POST_DIV_PIXCLK_MASK,
-+ /* maxPixelClockPLLPostDivider*/
-+ 1,/* minPLLRefDivider*/
-+ PLL_REF_DIV__PLL_REF_DIV_MASK,/* maxPLLRefDivider*/
-+ 13500,
-+ /* when 0 use minInputPxlClkPLLFrequencyInKHz from firmwareInfo*/
-+ 27000,
-+ /* when 0 use maxInputPxlClkPLLFrequencyInKHz from firmwareInfo*/
-+ FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM,
-+ /*numberOfFractFBDividerDecimalPoints*/
-+ FRACT_FB_DIVIDER_DEC_POINTS_MAX_NUM,
-+/*number of decimal point to round off for fractional feedback divider value*/
-+ clk_src_init_data->ctx
-+ };
-+
-+ struct pll_clock_source *base = &pll_cs_dce110->base;
-+ struct clock_source *superbase = &base->base;
-+
-+ if (!dal_pll_clock_source_construct(base, clk_src_init_data)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ superbase->funcs = &funcs;
-+
-+ superbase->is_clock_source_with_fixed_freq = false;
-+ superbase->clk_sharing_lvl = CLOCK_SHARING_LEVEL_DISPLAY_PORT_SHAREABLE;
-+
-+ pll_cs_dce110->registers = NULL;
-+
-+/* PLL3 should not be used although it is available in online register spec */
-+ if ((superbase->clk_src_id != CLOCK_SOURCE_ID_PLL1)
-+ && (superbase->clk_src_id != CLOCK_SOURCE_ID_PLL0)) {
-+
-+
-+ ASSERT_CRITICAL(false);
-+ goto failure;
-+ }
-+
-+/* From Driver side PLL0 is now used for non DP timing also,
-+ * so it supports all signals except Wireless.
-+ * Wireless signal type does not require a PLL clock source,
-+ * so we will not waste a clock on it.
-+*/
-+ superbase->output_signals &= ~SIGNAL_TYPE_WIRELESS;
-+
-+ if (!dal_calc_pll_clock_source_max_vco_init(
-+ &pll_cs_dce110->calc_pll_clock_source,
-+ &calc_pll_cs_init_data)) {
-+ ASSERT_CRITICAL(false);
-+ goto failure;
-+ }
-+
-+ if (base->ref_freq_khz == 48000) {
-+ calc_pll_cs_init_data_hdmi.
-+ min_override_input_pxl_clk_pll_freq_khz = 24000;
-+ calc_pll_cs_init_data_hdmi.
-+ max_override_input_pxl_clk_pll_freq_khz = 48000;
-+ } else if (base->ref_freq_khz == 100000) {
-+ calc_pll_cs_init_data_hdmi.
-+ min_override_input_pxl_clk_pll_freq_khz = 25000;
-+ calc_pll_cs_init_data_hdmi.
-+ max_override_input_pxl_clk_pll_freq_khz = 50000;
-+ }
-+
-+ if (!dal_calc_pll_clock_source_max_vco_init(
-+ &pll_cs_dce110->calc_pll_clock_source_hdmi,
-+ &calc_pll_cs_init_data_hdmi)) {
-+ ASSERT_CRITICAL(false);
-+ goto failure;
-+ }
-+
-+ switch (superbase->clk_src_id) {
-+ case CLOCK_SOURCE_ID_PLL0:
-+ pll_cs_dce110->pixclkx_resync_cntl = mmPIXCLK0_RESYNC_CNTL;
-+ pll_cs_dce110->ppll_fb_div = mmBPHYC_PLL0_PLL_FB_DIV;
-+ pll_cs_dce110->ppll_ref_div = mmBPHYC_PLL0_PLL_REF_DIV;
-+ pll_cs_dce110->ppll_post_div = mmBPHYC_PLL0_PLL_POST_DIV;
-+ pll_cs_dce110->pxpll_ds_cntl = mmBPHYC_PLL0_PLL_DS_CNTL;
-+ pll_cs_dce110->pxpll_ss_cntl = mmBPHYC_PLL0_PLL_SS_CNTL;
-+ pll_cs_dce110->pxpll_ss_dsfrac =
-+ mmBPHYC_PLL0_PLL_SS_AMOUNT_DSFRAC;
-+ pll_cs_dce110->pxpll_cntl = mmBPHYC_PLL0_PLL_CNTL;
-+ break;
-+ case CLOCK_SOURCE_ID_PLL1:
-+ pll_cs_dce110->pixclkx_resync_cntl = mmPIXCLK1_RESYNC_CNTL;
-+ pll_cs_dce110->ppll_fb_div = mmBPHYC_PLL1_PLL_FB_DIV;
-+ pll_cs_dce110->ppll_ref_div = mmBPHYC_PLL1_PLL_REF_DIV;
-+ pll_cs_dce110->ppll_post_div = mmBPHYC_PLL1_PLL_POST_DIV;
-+ pll_cs_dce110->pxpll_ds_cntl = mmBPHYC_PLL1_PLL_DS_CNTL;
-+ pll_cs_dce110->pxpll_ss_cntl = mmBPHYC_PLL1_PLL_SS_CNTL;
-+ pll_cs_dce110->pxpll_ss_dsfrac =
-+ mmBPHYC_PLL1_PLL_SS_AMOUNT_DSFRAC;
-+ pll_cs_dce110->pxpll_cntl = mmBPHYC_PLL1_PLL_CNTL;
-+ break;
-+ case CLOCK_SOURCE_ID_PLL2:
-+ /* PLL2 is not supported */
-+ default:
-+ break;
-+ }
-+
-+ controllers_num = dal_adapter_service_get_controllers_num(
-+ superbase->adapter_service);
-+
-+ pll_cs_dce110->registers = dc_service_alloc(
-+ clk_src_init_data->ctx,
-+ sizeof(struct registers) * controllers_num);
-+
-+ if (pll_cs_dce110->registers == NULL) {
-+ ASSERT_CRITICAL(false);
-+ goto failure;
-+ }
-+
-+ /* Assign register address. No break between cases */
-+ switch (controllers_num) {
-+ case 6:
-+ pll_cs_dce110->registers[5].dp_dtox_phase =
-+ mmDP_DTO5_PHASE;
-+ pll_cs_dce110->registers[5].dp_dtox_modulo =
-+ mmDP_DTO5_MODULO;
-+ pll_cs_dce110->registers[5].crtcx_pixel_rate_cntl =
-+ mmCRTC5_PIXEL_RATE_CNTL;
-+ /* fall through*/
-+
-+ case 5:
-+ pll_cs_dce110->registers[4].dp_dtox_phase =
-+ mmDP_DTO4_PHASE;
-+ pll_cs_dce110->registers[4].dp_dtox_modulo =
-+ mmDP_DTO4_MODULO;
-+ pll_cs_dce110->registers[4].crtcx_pixel_rate_cntl =
-+ mmCRTC4_PIXEL_RATE_CNTL;
-+ /* fall through*/
-+
-+ case 4:
-+ pll_cs_dce110->registers[3].dp_dtox_phase =
-+ mmDP_DTO3_PHASE;
-+ pll_cs_dce110->registers[3].dp_dtox_modulo =
-+ mmDP_DTO3_MODULO;
-+ pll_cs_dce110->registers[3].crtcx_pixel_rate_cntl =
-+ mmCRTC3_PIXEL_RATE_CNTL;
-+ /* fall through*/
-+
-+ case 3:
-+ pll_cs_dce110->registers[2].dp_dtox_phase =
-+ mmDP_DTO2_PHASE;
-+ pll_cs_dce110->registers[2].dp_dtox_modulo =
-+ mmDP_DTO2_MODULO;
-+ pll_cs_dce110->registers[2].crtcx_pixel_rate_cntl =
-+ mmCRTC2_PIXEL_RATE_CNTL;
-+ /* fall through*/
-+
-+ case 2:
-+ pll_cs_dce110->registers[1].dp_dtox_phase =
-+ mmDP_DTO1_PHASE;
-+ pll_cs_dce110->registers[1].dp_dtox_modulo =
-+ mmDP_DTO1_MODULO;
-+ pll_cs_dce110->registers[1].crtcx_pixel_rate_cntl =
-+ mmCRTC1_PIXEL_RATE_CNTL;
-+ /* fall through*/
-+
-+ case 1:
-+ pll_cs_dce110->registers[0].dp_dtox_phase =
-+ mmDP_DTO0_PHASE;
-+ pll_cs_dce110->registers[0].dp_dtox_modulo =
-+ mmDP_DTO0_MODULO;
-+ pll_cs_dce110->registers[0].crtcx_pixel_rate_cntl =
-+ mmCRTC0_PIXEL_RATE_CNTL;
-+
-+ break;
-+
-+ default:
-+ ASSERT_CRITICAL(false);
-+ goto failure;
-+ }
-+
-+ ss_info_from_atombios_create(pll_cs_dce110);
-+
-+ return true;
-+
-+failure:
-+ destruct(pll_cs_dce110);
-+
-+ return false;
-+}
-+
-+struct clock_source *dal_pll_clock_source_dce110_create(
-+ struct clock_source_init_data *clk_src_init_data)
-+{
-+ struct pll_clock_source_dce110 *clk_src =
-+ dc_service_alloc(clk_src_init_data->ctx, sizeof(struct pll_clock_source_dce110));
-+
-+ if (clk_src == NULL)
-+ return NULL;
-+
-+ if (!construct(clk_src, clk_src_init_data)) {
-+ dc_service_free(clk_src_init_data->ctx, clk_src);
-+ return NULL;
-+ }
-+ return &(clk_src->base.base);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce110/pll_clock_source_dce110.h b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/pll_clock_source_dce110.h
-new file mode 100644
-index 0000000..166b29a
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/pll_clock_source_dce110.h
-@@ -0,0 +1,55 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef __DAL_PLL_CLOCK_SOURCE_DCE110_H__
-+#define __DAL_PLL_CLOCK_SOURCE_DCE110_H__
-+
-+#include "../pll_clock_source.h"
-+#include "../calc_pll_clock_source.h"
-+
-+struct pll_clock_source_dce110 {
-+ struct pll_clock_source base;
-+
-+ struct calc_pll_clock_source calc_pll_clock_source;
-+/* object for normal circumstances, SS = 0 or SS >= 0.2% (LVDS or DP)
-+ * or even for SS =~0.02 (DVI) */
-+
-+ struct calc_pll_clock_source calc_pll_clock_source_hdmi;
-+/* object for HDMI no SS or SS <= 0.06% */
-+
-+ struct registers *registers;
-+
-+ uint32_t pixclkx_resync_cntl;
-+ uint32_t ppll_fb_div;
-+ uint32_t ppll_ref_div;
-+ uint32_t ppll_post_div;
-+ uint32_t pxpll_ds_cntl;
-+ uint32_t pxpll_ss_cntl;
-+ uint32_t pxpll_ss_dsfrac;
-+ uint32_t pxpll_cntl;
-+};
-+
-+struct clock_source *dal_pll_clock_source_dce110_create(
-+ struct clock_source_init_data *clk_src_init_data);
-+
-+#endif /*__DAL_PLL_CLOCK_SOURCE_DCE110__*/
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce110/vce_clock_source_dce110.c b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/vce_clock_source_dce110.c
-new file mode 100644
-index 0000000..ce59228
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/vce_clock_source_dce110.c
-@@ -0,0 +1,193 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#include "dal_services.h"
-+#include "vce_clock_source_dce110.h"
-+#include "include/clock_source_types.h"
-+#include "include/bios_parser_interface.h"
-+#include "include/logger_interface.h"
-+
-+struct vce_clock_source_dce110 {
-+ struct clock_source base;
-+ uint32_t ref_freq_khz;
-+};
-+
-+static uint32_t get_pix_clk_dividers(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings)
-+{
-+ struct vce_clock_source_dce110 *vce_clk_src_dce110 =
-+ container_of(
-+ clk_src,
-+ struct vce_clock_source_dce110,
-+ base);
-+ if (pix_clk_params == NULL ||
-+ pll_settings == NULL ||
-+ pix_clk_params->requested_pix_clk == 0) {
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s: Invalid parameters!!", __func__);
-+ return MAX_PLL_CALC_ERROR;
-+ }
-+
-+ dc_service_memset(pll_settings, 0, sizeof(struct pll_settings));
-+ pll_settings->reference_freq = vce_clk_src_dce110->ref_freq_khz;
-+ pll_settings->actual_pix_clk =
-+ pix_clk_params->requested_pix_clk;
-+ pll_settings->adjusted_pix_clk =
-+ pix_clk_params->requested_pix_clk;
-+ pll_settings->calculated_pix_clk =
-+ pix_clk_params->requested_pix_clk;
-+
-+ return 0;
-+}
-+static bool program_pix_clk(struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings)
-+{
-+ struct bp_pixel_clock_parameters bp_pix_clk_params = { 0 };
-+
-+ if (pll_settings->actual_pix_clk == 0)
-+ return false;
-+ /* this is SimNow for Nutmeg*/
-+
-+ bp_pix_clk_params.controller_id = pix_clk_params->controller_id;
-+ bp_pix_clk_params.pll_id = clk_src->clk_src_id;
-+ bp_pix_clk_params.target_pixel_clock = pll_settings->actual_pix_clk;
-+ bp_pix_clk_params.encoder_object_id = pix_clk_params->encoder_object_id;
-+ bp_pix_clk_params.signal_type = pix_clk_params->signal_type;
-+
-+ if (dal_bios_parser_set_pixel_clock(clk_src->bios_parser,
-+ &bp_pix_clk_params) == BP_RESULT_OK)
-+ return true;
-+
-+ return false;
-+}
-+
-+static bool power_down_pll(struct clock_source *clk_src,
-+ enum controller_id controller_id)
-+{
-+ return true;
-+}
-+
-+static void destruct(
-+ struct vce_clock_source_dce110 *vce_clk_src)
-+{
-+
-+}
-+
-+static void destroy(
-+ struct clock_source **clk_src)
-+{
-+ struct vce_clock_source_dce110 *vce_clk_src;
-+
-+ vce_clk_src =
-+ container_of(*clk_src, struct vce_clock_source_dce110, base);
-+
-+ destruct(vce_clk_src);
-+ dc_service_free((*clk_src)->ctx, vce_clk_src);
-+
-+ *clk_src = NULL;
-+}
-+
-+static const struct clock_source_impl funcs = {
-+ .program_pix_clk = program_pix_clk,
-+ .adjust_pll_pixel_rate = dal_clock_source_base_adjust_pll_pixel_rate,
-+ .adjust_dto_pixel_rate = dal_clock_source_base_adjust_dto_pix_rate,
-+ .retrieve_pll_pix_rate_hz =
-+ dal_clock_source_base_retrieve_pll_pix_rate_hz,
-+ .get_pix_clk_dividers = get_pix_clk_dividers,
-+ .destroy = destroy,
-+ .retrieve_dto_pix_rate_hz =
-+ dal_clock_source_base_retrieve_dto_pix_rate_hz,
-+ .power_down_pll = power_down_pll,
-+};
-+
-+static bool construct(
-+ struct vce_clock_source_dce110 *vce_clk_src,
-+ struct clock_source_init_data *clk_src_init_data)
-+{
-+ struct firmware_info fw_info = { { 0 } };
-+
-+ if (!dal_clock_source_construct(
-+ &vce_clk_src->base, clk_src_init_data)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ if (vce_clk_src->base.clk_src_id != CLOCK_SOURCE_ID_VCE) {
-+ dal_logger_write(clk_src_init_data->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Invalid ClockSourceId = %d!\n",
-+ vce_clk_src->base.clk_src_id);
-+ ASSERT_CRITICAL(false);
-+ dal_logger_write(clk_src_init_data->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Failed to create DCE110VceClockSource.\n");
-+ return false;
-+ }
-+
-+ vce_clk_src->base.funcs = &funcs;
-+ vce_clk_src->base.clk_sharing_lvl = CLOCK_SHARING_LEVEL_NOT_SHAREABLE;
-+ vce_clk_src->base.is_clock_source_with_fixed_freq = false;
-+
-+
-+ /*VCE clock source only supports SignalType_Wireless*/
-+ vce_clk_src->base.output_signals |= SIGNAL_TYPE_WIRELESS;
-+
-+ /*Get Reference frequency, Input frequency range into PLL
-+ * and Output frequency range of the PLL
-+ * from ATOMBIOS Data table */
-+ if (dal_bios_parser_get_firmware_info(
-+ vce_clk_src->base.bios_parser,
-+ &fw_info) != BP_RESULT_OK)
-+ return false;
-+
-+ vce_clk_src->ref_freq_khz = fw_info.pll_info.crystal_frequency;
-+
-+ return true;
-+}
-+
-+
-+struct clock_source *dal_vce_clock_source_dce110_create(
-+ struct clock_source_init_data *clk_src_init_data)
-+
-+{
-+ struct vce_clock_source_dce110 *clk_src;
-+
-+ clk_src = dc_service_alloc(clk_src_init_data->ctx, sizeof(struct vce_clock_source_dce110));
-+
-+ if (clk_src == NULL)
-+ return NULL;
-+
-+ if (!construct(clk_src, clk_src_init_data)) {
-+ dc_service_free(clk_src_init_data->ctx, clk_src);
-+ return NULL;
-+ }
-+
-+ return &clk_src->base;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce110/vce_clock_source_dce110.h b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/vce_clock_source_dce110.h
-new file mode 100644
-index 0000000..227b169
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce110/vce_clock_source_dce110.h
-@@ -0,0 +1,32 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef __DAL_VCE_CLOCK_SOURCE_DCE110__
-+#define __DAL_VCE_CLOCK_SOURCE_DCE110__
-+
-+#include "../clock_source.h"
-+
-+struct clock_source *dal_vce_clock_source_dce110_create(
-+ struct clock_source_init_data *clk_src_init_data);
-+
-+#endif /*__DAL_VCE_CLOCK_SOURCE_DCE110__*/
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/display_clock.c b/drivers/gpu/drm/amd/dal/dc/gpu/display_clock.c
-new file mode 100644
-index 0000000..a11aa84
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/display_clock.c
-@@ -0,0 +1,204 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "display_clock.h"
-+#include "adapter_service_interface.h"
-+
-+void dal_display_clock_base_set_dp_ref_clock_source(
-+ struct display_clock *disp_clk,
-+ enum clock_source_id clk_src)
-+{/*must be implemented in derived*/
-+
-+}
-+
-+void dal_display_clock_base_set_clock_state(struct display_clock *disp_clk,
-+ struct display_clock_state clk_state)
-+{
-+ /*Implemented only in DCE81*/
-+}
-+struct display_clock_state dal_display_clock_base_get_clock_state(
-+ struct display_clock *disp_clk)
-+{
-+ /*Implemented only in DCE81*/
-+ struct display_clock_state state = {0};
-+ return state;
-+}
-+uint32_t dal_display_clock_base_get_dfs_bypass_threshold(
-+ struct display_clock *disp_clk)
-+{
-+ /*Implemented only in DCE81*/
-+ return 0;
-+}
-+
-+bool dal_display_clock_construct_base(
-+ struct display_clock *base,
-+ struct dc_context *ctx,
-+ struct adapter_service *as)
-+{
-+ base->ctx = ctx;
-+ base->id = CLOCK_SOURCE_ID_DCPLL;
-+ base->min_display_clk_threshold_khz = 0;
-+ base->as = as;
-+
-+/* Initially set current min clocks state to invalid since we
-+ * cannot make any assumption about PPLIB's initial state. This will be updated
-+ * by HWSS via SetMinClocksState() on first mode set prior to programming
-+ * state dependent clocks.*/
-+ base->cur_min_clks_state = CLOCKS_STATE_INVALID;
-+
-+ return true;
-+}
-+
-+void dal_display_clock_destroy(struct display_clock **disp_clk)
-+{
-+ if (!disp_clk || !*disp_clk) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ (*disp_clk)->funcs->destroy(disp_clk);
-+
-+ *disp_clk = NULL;
-+}
-+
-+bool dal_display_clock_validate(
-+ struct display_clock *disp_clk,
-+ struct min_clock_params *params)
-+{
-+ return disp_clk->funcs->validate(disp_clk, params);
-+}
-+
-+uint32_t dal_display_clock_calculate_min_clock(
-+ struct display_clock *disp_clk,
-+ uint32_t path_num,
-+ struct min_clock_params *params)
-+{
-+ return disp_clk->funcs->calculate_min_clock(disp_clk, path_num, params);
-+}
-+
-+uint32_t dal_display_clock_get_validation_clock(struct display_clock *disp_clk)
-+{
-+ return disp_clk->funcs->get_validation_clock(disp_clk);
-+}
-+
-+void dal_display_clock_set_clock(
-+ struct display_clock *disp_clk,
-+ uint32_t requested_clock_khz)
-+{
-+ disp_clk->funcs->set_clock(disp_clk, requested_clock_khz);
-+}
-+
-+uint32_t dal_display_clock_get_clock(struct display_clock *disp_clk)
-+{
-+ return disp_clk->funcs->get_clock(disp_clk);
-+}
-+
-+enum clocks_state dal_display_clock_get_min_clocks_state(
-+ struct display_clock *disp_clk)
-+{
-+ return disp_clk->funcs->get_min_clocks_state(disp_clk);
-+}
-+
-+enum clocks_state dal_display_clock_get_required_clocks_state(
-+ struct display_clock *disp_clk,
-+ struct state_dependent_clocks *req_clocks)
-+{
-+ return disp_clk->funcs->get_required_clocks_state(disp_clk, req_clocks);
-+}
-+
-+bool dal_display_clock_set_min_clocks_state(
-+ struct display_clock *disp_clk,
-+ enum clocks_state clocks_state)
-+{
-+ return disp_clk->funcs->set_min_clocks_state(disp_clk, clocks_state);
-+}
-+
-+uint32_t dal_display_clock_get_dp_ref_clk_frequency(
-+ struct display_clock *disp_clk)
-+{
-+ return disp_clk->funcs->get_dp_ref_clk_frequency(disp_clk);
-+}
-+
-+/*the second parameter of "switchreferenceclock" is
-+ * a dummy argument for all pre dce 6.0 versions*/
-+
-+void dal_display_clock_switch_reference_clock(
-+ struct display_clock *disp_clk,
-+ bool use_external_ref_clk,
-+ uint32_t requested_clk_khz)
-+{
-+ /* TODO: requires Asic Control*/
-+ /*
-+ struct ac_pixel_clk_params params;
-+ struct asic_control *ac =
-+ dal_adapter_service_get_asic_control(disp_clk->as);
-+ dc_service_memset(&params, 0, sizeof(struct ac_pixel_clk_params));
-+
-+ params.tgt_pixel_clk_khz = requested_clk_khz;
-+ params.flags.SET_EXTERNAL_REF_DIV_SRC = use_external_ref_clk;
-+ params.pll_id = disp_clk->id;
-+ dal_asic_control_program_display_engine_pll(ac, &params);
-+ */
-+}
-+
-+void dal_display_clock_set_dp_ref_clock_source(
-+ struct display_clock *disp_clk,
-+ enum clock_source_id clk_src)
-+{
-+ disp_clk->funcs->set_dp_ref_clock_source(disp_clk, clk_src);
-+}
-+
-+void dal_display_clock_store_max_clocks_state(
-+ struct display_clock *disp_clk,
-+ enum clocks_state max_clocks_state)
-+{
-+ disp_clk->funcs->store_max_clocks_state(disp_clk, max_clocks_state);
-+}
-+
-+void dal_display_clock_set_clock_state(
-+ struct display_clock *disp_clk,
-+ struct display_clock_state clk_state)
-+{
-+ disp_clk->funcs->set_clock_state(disp_clk, clk_state);
-+}
-+
-+struct display_clock_state dal_display_clock_get_clock_state(
-+ struct display_clock *disp_clk)
-+{
-+ return disp_clk->funcs->get_clock_state(disp_clk);
-+}
-+
-+uint32_t dal_display_clock_get_dfs_bypass_threshold(
-+ struct display_clock *disp_clk)
-+{
-+ return disp_clk->funcs->get_dfs_bypass_threshold(disp_clk);
-+}
-+
-+void dal_display_clock_invalid_clock_state(
-+ struct display_clock *disp_clk)
-+{
-+ disp_clk->cur_min_clks_state = CLOCKS_STATE_INVALID;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/display_clock.h b/drivers/gpu/drm/amd/dal/dc/gpu/display_clock.h
-new file mode 100644
-index 0000000..845393b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/display_clock.h
-@@ -0,0 +1,82 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DISPLAY_CLOCK_H__
-+#define __DAL_DISPLAY_CLOCK_H__
-+
-+#include "include/display_clock_interface.h"
-+
-+struct display_clock_funcs {
-+ void (*destroy)(struct display_clock **to_destroy);
-+ bool (*validate)(struct display_clock *disp_clk,
-+ struct min_clock_params *params);
-+ uint32_t (*calculate_min_clock)(struct display_clock *disp_clk,
-+ uint32_t path_num, struct min_clock_params *params);
-+ uint32_t (*get_validation_clock)(struct display_clock *disp_clk);
-+ void (*set_clock)(struct display_clock *disp_clk,
-+ uint32_t requested_clock_khz);
-+ uint32_t (*get_clock)(struct display_clock *disp_clk);
-+ enum clocks_state (*get_min_clocks_state)(
-+ struct display_clock *disp_clk);
-+ enum clocks_state (*get_required_clocks_state)(
-+ struct display_clock *disp_clk,
-+ struct state_dependent_clocks *req_clocks);
-+ bool (*set_min_clocks_state)(struct display_clock *disp_clk,
-+ enum clocks_state clocks_state);
-+ uint32_t (*get_dp_ref_clk_frequency)(struct display_clock *disp_clk);
-+ void (*set_dp_ref_clock_source)(struct display_clock *disp_clk,
-+ enum clock_source_id clk_src);
-+ void (*store_max_clocks_state)(struct display_clock *disp_clk,
-+ enum clocks_state max_clocks_state);
-+ void (*set_clock_state)(struct display_clock *disp_clk,
-+ struct display_clock_state clk_state);
-+ struct display_clock_state (*get_clock_state)(
-+ struct display_clock *disp_clk);
-+ uint32_t (*get_dfs_bypass_threshold)(struct display_clock *disp_clk);
-+};
-+
-+struct display_clock {
-+ struct dc_context *ctx;
-+ const struct display_clock_funcs *funcs;
-+ uint32_t min_display_clk_threshold_khz;
-+ enum clock_source_id id;
-+ struct adapter_service *as;
-+
-+ enum clocks_state cur_min_clks_state;
-+};
-+void dal_display_clock_base_set_dp_ref_clock_source(
-+ struct display_clock *disp_clk,
-+ enum clock_source_id clk_src);
-+struct display_clock_state dal_display_clock_base_get_clock_state(
-+ struct display_clock *disp_clk);
-+uint32_t dal_display_clock_base_get_dfs_bypass_threshold(
-+ struct display_clock *disp_clk);
-+void dal_display_clock_base_set_clock_state(struct display_clock *disp_clk,
-+ struct display_clock_state clk_state);
-+bool dal_display_clock_construct_base(
-+ struct display_clock *base,
-+ struct dc_context *ctx,
-+ struct adapter_service *as);
-+#endif /* __DAL_DISPLAY_CLOCK_H__*/
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/divider_range.c b/drivers/gpu/drm/amd/dal/dc/gpu/divider_range.c
-new file mode 100644
-index 0000000..3b04447
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/divider_range.c
-@@ -0,0 +1,127 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#include "dal_services.h"
-+#include "divider_range.h"
-+
-+bool dal_divider_range_construct(
-+ struct divider_range *div_range,
-+ uint32_t range_start,
-+ uint32_t range_step,
-+ uint32_t did_min,
-+ uint32_t did_max)
-+{
-+ div_range->div_range_start = range_start;
-+ div_range->div_range_step = range_step;
-+ div_range->did_min = did_min;
-+ div_range->did_max = did_max;
-+
-+ if (div_range->div_range_step == 0) {
-+ div_range->div_range_step = 1;
-+ /*div_range_step cannot be zero*/
-+ BREAK_TO_DEBUGGER();
-+ }
-+ /* Calculate this based on the other inputs.*/
-+ /* See DividerRange.h for explanation of */
-+ /* the relationship between divider id (DID) and a divider.*/
-+ /* Number of Divider IDs = (Maximum Divider ID - Minimum Divider ID)*/
-+ /* Maximum divider identified in this range =
-+ * (Number of Divider IDs)*Step size between dividers
-+ * + The start of this range.*/
-+ div_range->div_range_end = (did_max - did_min) * range_step
-+ + range_start;
-+ return true;
-+}
-+
-+static uint32_t dal_divider_range_calc_divider(
-+ struct divider_range *div_range,
-+ uint32_t did)
-+{
-+ /* Is this DID within our range?*/
-+ if ((did < div_range->did_min) || (did >= div_range->did_max))
-+ return INVALID_DIVIDER;
-+
-+ return ((did - div_range->did_min) * div_range->div_range_step)
-+ + div_range->div_range_start;
-+
-+}
-+
-+static uint32_t dal_divider_range_calc_did(
-+ struct divider_range *div_range,
-+ uint32_t div)
-+{
-+ uint32_t did;
-+ /* Check before dividing.*/
-+ if (div_range->div_range_step == 0) {
-+ div_range->div_range_step = 1;
-+ /*div_range_step cannot be zero*/
-+ BREAK_TO_DEBUGGER();
-+ }
-+ /* Is this divider within our range?*/
-+ if ((div < div_range->div_range_start)
-+ || (div >= div_range->div_range_end))
-+ return INVALID_DID;
-+/* did = (divider - range_start + (range_step-1)) / range_step) + did_min*/
-+ did = div - div_range->div_range_start;
-+ did += div_range->div_range_step - 1;
-+ did /= div_range->div_range_step;
-+ did += div_range->did_min;
-+ return did;
-+}
-+
-+uint32_t dal_divider_range_get_divider(
-+ struct divider_range *div_range,
-+ uint32_t ranges_num,
-+ uint32_t did)
-+{
-+ uint32_t div = INVALID_DIVIDER;
-+ uint32_t i;
-+
-+ for (i = 0; i < ranges_num; i++) {
-+ /* Calculate divider with given divider ID*/
-+ div = dal_divider_range_calc_divider(&div_range[i], did);
-+ /* Found a valid return divider*/
-+ if (div != INVALID_DIVIDER)
-+ break;
-+ }
-+ return div;
-+}
-+uint32_t dal_divider_range_get_did(
-+ struct divider_range *div_range,
-+ uint32_t ranges_num,
-+ uint32_t divider)
-+{
-+ uint32_t did = INVALID_DID;
-+ uint32_t i;
-+
-+ for (i = 0; i < ranges_num; i++) {
-+ /* CalcDid returns InvalidDid if a divider ID isn't found*/
-+ did = dal_divider_range_calc_did(&div_range[i], divider);
-+ /* Found a valid return did*/
-+ if (did != INVALID_DID)
-+ break;
-+ }
-+ return did;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/divider_range.h b/drivers/gpu/drm/amd/dal/dc/gpu/divider_range.h
-new file mode 100644
-index 0000000..2ec1034
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/divider_range.h
-@@ -0,0 +1,63 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DIVIDER_RANGE_H__
-+#define __DAL_DIVIDER_RANGE_H__
-+
-+enum divider_error_types {
-+ INVALID_DID = 0,
-+ INVALID_DIVIDER = 1
-+};
-+
-+struct divider_range {
-+ uint32_t div_range_start;
-+ /* The end of this range of dividers.*/
-+ uint32_t div_range_end;
-+ /* The distance between each divider in this range.*/
-+ uint32_t div_range_step;
-+ /* The divider id for the lowest divider.*/
-+ uint32_t did_min;
-+ /* The divider id for the highest divider.*/
-+ uint32_t did_max;
-+};
-+
-+bool dal_divider_range_construct(
-+ struct divider_range *div_range,
-+ uint32_t range_start,
-+ uint32_t range_step,
-+ uint32_t did_min,
-+ uint32_t did_max);
-+
-+uint32_t dal_divider_range_get_divider(
-+ struct divider_range *div_range,
-+ uint32_t ranges_num,
-+ uint32_t did);
-+uint32_t dal_divider_range_get_did(
-+ struct divider_range *div_range,
-+ uint32_t ranges_num,
-+ uint32_t divider);
-+
-+
-+#endif /* __DAL_DIVIDER_RANGE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/ext_clock_source.c b/drivers/gpu/drm/amd/dal/dc/gpu/ext_clock_source.c
-new file mode 100644
-index 0000000..ac27cd7
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/ext_clock_source.c
-@@ -0,0 +1,119 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/clock_source_types.h"
-+#include "include/bios_parser_interface.h"
-+#include "include/logger_interface.h"
-+#include "ext_clock_source.h"
-+
-+uint32_t dal_ext_clock_source_get_pix_clk_dividers(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings)
-+{
-+ struct ext_clock_source *ext_clk_src = container_of(
-+ clk_src,
-+ struct ext_clock_source,
-+ base);
-+
-+ if (pix_clk_params == NULL ||
-+ pll_settings == NULL ||
-+ pix_clk_params->requested_pix_clk == 0) {
-+ dal_logger_write(clk_src->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s: Invalid parameters!!", __func__);
-+ return MAX_PLL_CALC_ERROR;
-+ }
-+
-+ dc_service_memset(pll_settings, 0, sizeof(struct pll_settings));
-+ pll_settings->adjusted_pix_clk = ext_clk_src->ext_clk_freq_khz;
-+ pll_settings->calculated_pix_clk = ext_clk_src->ext_clk_freq_khz;
-+ pll_settings->actual_pix_clk =
-+ pix_clk_params->requested_pix_clk;
-+ return 0;
-+}
-+
-+bool dal_ext_clock_source_program_pix_clk(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings)
-+{
-+ struct bp_pixel_clock_parameters bp_pix_clk_params = {0};
-+
-+ bp_pix_clk_params.controller_id = pix_clk_params->controller_id;
-+ bp_pix_clk_params.pll_id = clk_src->clk_src_id;
-+ bp_pix_clk_params.target_pixel_clock =
-+ pix_clk_params->requested_pix_clk;
-+ bp_pix_clk_params.encoder_object_id = pix_clk_params->encoder_object_id;
-+ bp_pix_clk_params.signal_type = pix_clk_params->signal_type;
-+ bp_pix_clk_params.dvo_config = pix_clk_params->dvo_cfg;
-+
-+
-+ if (dal_bios_parser_set_pixel_clock(
-+ clk_src->bios_parser,
-+ &bp_pix_clk_params) == BP_RESULT_OK)
-+ return true;
-+ return false;
-+
-+}
-+
-+bool dal_ext_clock_source_power_down_pll(struct clock_source *clk_src,
-+ enum controller_id controller_id)
-+{
-+ return true;
-+}
-+
-+bool dal_ext_clock_source_construct(
-+ struct ext_clock_source *ext_clk_src,
-+ struct clock_source_init_data *clk_src_init_data)
-+{
-+ struct firmware_info fw_info = { { 0 } };
-+
-+ if (!dal_clock_source_construct(
-+ &ext_clk_src->base, clk_src_init_data)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ ext_clk_src->base.clk_sharing_lvl =
-+ CLOCK_SHARING_LEVEL_DISPLAY_PORT_SHAREABLE;
-+ ext_clk_src->base.is_clock_source_with_fixed_freq = true;
-+ /* ExtClock has fixed frequency,
-+ * so it supports only DisplayPort signals.*/
-+ ext_clk_src->base.output_signals =
-+ SIGNAL_TYPE_DISPLAY_PORT |
-+ SIGNAL_TYPE_DISPLAY_PORT_MST |
-+ SIGNAL_TYPE_EDP;
-+
-+ /*Get External clock frequency from ATOMBIOS Data table */
-+ if (dal_bios_parser_get_firmware_info(
-+ ext_clk_src->base.bios_parser,
-+ &fw_info) != BP_RESULT_OK)
-+ return false;
-+ ext_clk_src->ext_clk_freq_khz = fw_info.
-+ external_clock_source_frequency_for_dp;
-+ return true;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/ext_clock_source.h b/drivers/gpu/drm/amd/dal/dc/gpu/ext_clock_source.h
-new file mode 100644
-index 0000000..bef1dc4
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/ext_clock_source.h
-@@ -0,0 +1,47 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef __DAL_EXT_CLOCK_SOURCE_H__
-+#define __DAL_EXT_CLOCK_SOURCE_H__
-+
-+#include "clock_source.h"
-+
-+struct ext_clock_source {
-+ struct clock_source base;
-+ uint32_t ext_clk_freq_khz;
-+};
-+
-+bool dal_ext_clock_source_construct(
-+ struct ext_clock_source *ext_cs,
-+ struct clock_source_init_data *clk_src_init_data);
-+bool dal_ext_clock_source_power_down_pll(struct clock_source *clk_src,
-+ enum controller_id controller_id);
-+uint32_t dal_ext_clock_source_get_pix_clk_dividers(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings);
-+bool dal_ext_clock_source_program_pix_clk(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings);
-+#endif /*__DAL_EXT_CLOCK_SOURCE_H__*/
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/pll_clock_source.c b/drivers/gpu/drm/amd/dal/dc/gpu/pll_clock_source.c
-new file mode 100644
-index 0000000..8bb0304
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/pll_clock_source.c
-@@ -0,0 +1,141 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/bios_parser_interface.h"
-+#include "pll_clock_source.h"
-+
-+bool dal_pll_clock_source_power_down_pll(
-+ struct clock_source *clk_src,
-+ enum controller_id controller_id)
-+{
-+
-+ enum bp_result bp_result;
-+ struct bp_pixel_clock_parameters bp_pixel_clock_params = {0};
-+
-+ /* If Pixel Clock is 0 it means Power Down Pll*/
-+ bp_pixel_clock_params.controller_id = controller_id;
-+ bp_pixel_clock_params.pll_id = clk_src->clk_src_id;
-+ bp_pixel_clock_params.flags.FORCE_PROGRAMMING_OF_PLL = 1;
-+
-+ /*Call ASICControl to process ATOMBIOS Exec table*/
-+ bp_result = dal_bios_parser_set_pixel_clock(
-+ clk_src->bios_parser,
-+ &bp_pixel_clock_params);
-+
-+ return bp_result == BP_RESULT_OK;
-+}
-+
-+bool dal_pll_clock_source_adjust_pix_clk(
-+ struct pll_clock_source *pll_clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings)
-+{
-+ uint32_t actual_pix_clk_khz = 0;
-+ uint32_t requested_clk_khz = 0;
-+ struct bp_adjust_pixel_clock_parameters bp_adjust_pixel_clock_params = {
-+ 0 };
-+ enum bp_result bp_result;
-+
-+ switch (pix_clk_params->signal_type) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A: {
-+ requested_clk_khz = pix_clk_params->requested_pix_clk;
-+
-+ switch (pix_clk_params->color_depth) {
-+ case COLOR_DEPTH_101010:
-+ requested_clk_khz = (requested_clk_khz * 5) >> 2;
-+ break; /* x1.25*/
-+ case COLOR_DEPTH_121212:
-+ requested_clk_khz = (requested_clk_khz * 6) >> 2;
-+ break; /* x1.5*/
-+ case COLOR_DEPTH_161616:
-+ requested_clk_khz = requested_clk_khz * 2;
-+ break; /* x2.0*/
-+ default:
-+ break;
-+ }
-+
-+ actual_pix_clk_khz = requested_clk_khz;
-+ }
-+ break;
-+
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP:
-+ requested_clk_khz = pix_clk_params->requested_sym_clk;
-+ actual_pix_clk_khz = pix_clk_params->requested_pix_clk;
-+ break;
-+
-+ default:
-+ requested_clk_khz = pix_clk_params->requested_pix_clk;
-+ actual_pix_clk_khz = pix_clk_params->requested_pix_clk;
-+ break;
-+ }
-+
-+ bp_adjust_pixel_clock_params.pixel_clock = requested_clk_khz;
-+ bp_adjust_pixel_clock_params.
-+ encoder_object_id = pix_clk_params->encoder_object_id;
-+ bp_adjust_pixel_clock_params.signal_type = pix_clk_params->signal_type;
-+ bp_adjust_pixel_clock_params.dvo_config = pix_clk_params->dvo_cfg;
-+ bp_adjust_pixel_clock_params.
-+ display_pll_config = pix_clk_params->disp_pll_cfg;
-+ bp_adjust_pixel_clock_params.
-+ ss_enable = pix_clk_params->flags.ENABLE_SS;
-+ bp_result = dal_bios_parser_adjust_pixel_clock(
-+ pll_clk_src->base.bios_parser,
-+ &bp_adjust_pixel_clock_params);
-+ if (bp_result == BP_RESULT_OK) {
-+ pll_settings->actual_pix_clk = actual_pix_clk_khz;
-+ pll_settings->adjusted_pix_clk =
-+ bp_adjust_pixel_clock_params.adjusted_pixel_clock;
-+ pll_settings->reference_divider =
-+ bp_adjust_pixel_clock_params.reference_divider;
-+ pll_settings->pix_clk_post_divider =
-+ bp_adjust_pixel_clock_params.pixel_clock_post_divider;
-+
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+bool dal_pll_clock_source_construct(
-+ struct pll_clock_source *pll_clk_src,
-+ struct clock_source_init_data *clk_src_init_data)
-+{
-+ struct firmware_info fw_info = { { 0 } };
-+
-+ if (!dal_clock_source_construct(
-+ &pll_clk_src->base,
-+ clk_src_init_data))
-+ return false;
-+
-+ if (dal_bios_parser_get_firmware_info(
-+ pll_clk_src->base.bios_parser,
-+ &fw_info) != BP_RESULT_OK)
-+ return false;
-+ pll_clk_src->ref_freq_khz = fw_info.pll_info.crystal_frequency;
-+
-+ return true;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/pll_clock_source.h b/drivers/gpu/drm/amd/dal/dc/gpu/pll_clock_source.h
-new file mode 100644
-index 0000000..8339e1f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/pll_clock_source.h
-@@ -0,0 +1,52 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef __DAL_PLL_CLOCK_SOURCE_H__
-+#define __DAL_PLL_CLOCK_SOURCE_H__
-+
-+#include "gpu/clock_source.h"
-+
-+struct pll_clock_source {
-+ struct clock_source base;
-+ uint32_t ref_freq_khz;
-+};
-+
-+struct delta_sigma_data {
-+ uint32_t feedback_amount;
-+ uint32_t nfrac_amount;
-+ uint32_t ds_frac_size;
-+ uint32_t ds_frac_amount;
-+};
-+
-+bool dal_pll_clock_source_construct(
-+ struct pll_clock_source *pll_clk_src,
-+ struct clock_source_init_data *clk_src_init_data);
-+
-+bool dal_pll_clock_source_adjust_pix_clk(
-+ struct pll_clock_source *pll_clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings);
-+bool dal_pll_clock_source_power_down_pll(
-+ struct clock_source *clk_src,
-+ enum controller_id controller_id);
-+#endif /*__DAL_PLL_CLOCK_SOURCE_H__*/
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/Makefile b/drivers/gpu/drm/amd/dal/dc/i2caux/Makefile
-new file mode 100644
-index 0000000..15902a8
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/Makefile
-@@ -0,0 +1,23 @@
-+#
-+# Makefile for the 'i2c' sub-component of DAL.
-+# It provides the control and status of HW i2c engine of the adapter.
-+
-+I2CAUX = aux_engine.o engine_base.o i2caux.o i2c_engine.o \
-+ i2c_generic_hw_engine.o i2c_hw_engine.o i2c_sw_engine.o
-+
-+AMD_DAL_I2CAUX = $(addprefix $(AMDDALPATH)/dc/i2caux/,$(I2CAUX))
-+
-+AMD_DAL_FILES += $(AMD_DAL_I2CAUX)
-+
-+
-+###############################################################################
-+# DCE 11x family
-+###############################################################################
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_0
-+I2CAUX_DCE110 = i2caux_dce110.o i2c_sw_engine_dce110.o i2c_hw_engine_dce110.o \
-+ aux_engine_dce110.o
-+
-+AMD_DAL_I2CAUX_DCE110 = $(addprefix $(AMDDALPATH)/dc/i2caux/dce110/,$(I2CAUX_DCE110))
-+
-+AMD_DAL_FILES += $(AMD_DAL_I2CAUX_DCE110)
-+endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/aux_engine.c b/drivers/gpu/drm/amd/dal/dc/i2caux/aux_engine.c
-new file mode 100644
-index 0000000..824ceec
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/aux_engine.c
-@@ -0,0 +1,568 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/i2caux_interface.h"
-+#include "engine.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "aux_engine.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+#include "include/link_service_types.h"
-+
-+/*
-+ * This unit
-+ */
-+
-+enum {
-+ AUX_INVALID_REPLY_RETRY_COUNTER = 1,
-+ AUX_TIMED_OUT_RETRY_COUNTER = 2,
-+ AUX_DEFER_RETRY_COUNTER = 6
-+};
-+
-+#define FROM_ENGINE(ptr) \
-+ container_of((ptr), struct aux_engine, base)
-+
-+enum i2caux_engine_type dal_aux_engine_get_engine_type(
-+ const struct engine *engine)
-+{
-+ return I2CAUX_ENGINE_TYPE_AUX;
-+}
-+
-+bool dal_aux_engine_acquire(
-+ struct engine *engine,
-+ struct ddc *ddc)
-+{
-+ struct aux_engine *aux_engine = FROM_ENGINE(engine);
-+
-+ enum gpio_result result;
-+
-+ result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
-+ GPIO_DDC_CONFIG_TYPE_MODE_AUX);
-+
-+ if (result != GPIO_RESULT_OK)
-+ return false;
-+
-+ if (!aux_engine->funcs->acquire_engine(aux_engine)) {
-+ dal_ddc_close(ddc);
-+ return false;
-+ }
-+
-+ engine->ddc = ddc;
-+
-+ return true;
-+}
-+
-+struct read_command_context {
-+ uint8_t *buffer;
-+ uint8_t current_read_length;
-+ uint32_t offset;
-+ enum i2caux_transaction_status status;
-+
-+ struct aux_request_transaction_data request;
-+ struct aux_reply_transaction_data reply;
-+
-+ uint8_t returned_byte;
-+
-+ uint32_t timed_out_retry_aux;
-+ uint32_t invalid_reply_retry_aux;
-+ uint32_t defer_retry_aux;
-+ uint32_t defer_retry_i2c;
-+ uint32_t invalid_reply_retry_aux_on_ack;
-+
-+ bool transaction_complete;
-+ bool operation_succeeded;
-+};
-+
-+static void process_read_reply(
-+ struct aux_engine *engine,
-+ struct read_command_context *ctx)
-+{
-+ engine->funcs->process_channel_reply(engine, &ctx->reply);
-+
-+ switch (ctx->reply.status) {
-+ case AUX_TRANSACTION_REPLY_AUX_ACK:
-+ ctx->defer_retry_aux = 0;
-+ if (ctx->returned_byte > ctx->current_read_length) {
-+ ctx->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR;
-+ ctx->operation_succeeded = false;
-+ } else if (ctx->returned_byte < ctx->current_read_length) {
-+ ctx->current_read_length -= ctx->returned_byte;
-+
-+ ctx->offset += ctx->returned_byte;
-+
-+ ++ctx->invalid_reply_retry_aux_on_ack;
-+
-+ if (ctx->invalid_reply_retry_aux_on_ack >
-+ AUX_INVALID_REPLY_RETRY_COUNTER) {
-+ ctx->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR;
-+ ctx->operation_succeeded = false;
-+ }
-+ } else {
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_SUCCEEDED;
-+ ctx->transaction_complete = true;
-+ ctx->operation_succeeded = true;
-+ }
-+ break;
-+ case AUX_TRANSACTION_REPLY_AUX_NACK:
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_NACK;
-+ ctx->operation_succeeded = false;
-+ break;
-+ case AUX_TRANSACTION_REPLY_AUX_DEFER:
-+ ++ctx->defer_retry_aux;
-+
-+ if (ctx->defer_retry_aux > AUX_DEFER_RETRY_COUNTER) {
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT;
-+ ctx->operation_succeeded = false;
-+ }
-+ break;
-+ case AUX_TRANSACTION_REPLY_I2C_DEFER:
-+ ctx->defer_retry_aux = 0;
-+
-+ ++ctx->defer_retry_i2c;
-+
-+ if (ctx->defer_retry_i2c > AUX_DEFER_RETRY_COUNTER) {
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT;
-+ ctx->operation_succeeded = false;
-+ }
-+ break;
-+ default:
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN;
-+ ctx->operation_succeeded = false;
-+ }
-+}
-+
-+static void process_read_request(
-+ struct aux_engine *engine,
-+ struct read_command_context *ctx)
-+{
-+ enum aux_channel_operation_result operation_result;
-+
-+ engine->funcs->submit_channel_request(engine, &ctx->request);
-+
-+ operation_result = engine->funcs->get_channel_status(
-+ engine, &ctx->returned_byte);
-+
-+ switch (operation_result) {
-+ case AUX_CHANNEL_OPERATION_SUCCEEDED:
-+ if (ctx->returned_byte > ctx->current_read_length) {
-+ ctx->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR;
-+ ctx->operation_succeeded = false;
-+ } else {
-+ ctx->timed_out_retry_aux = 0;
-+ ctx->invalid_reply_retry_aux = 0;
-+
-+ ctx->reply.length = ctx->returned_byte;
-+ ctx->reply.data = ctx->buffer;
-+
-+ process_read_reply(engine, ctx);
-+ }
-+ break;
-+ case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY:
-+ ++ctx->invalid_reply_retry_aux;
-+
-+ if (ctx->invalid_reply_retry_aux >
-+ AUX_INVALID_REPLY_RETRY_COUNTER) {
-+ ctx->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR;
-+ ctx->operation_succeeded = false;
-+ } else
-+ dc_service_delay_in_microseconds(engine->base.ctx, 400);
-+ break;
-+ case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT:
-+ ++ctx->timed_out_retry_aux;
-+
-+ if (ctx->timed_out_retry_aux > AUX_TIMED_OUT_RETRY_COUNTER) {
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT;
-+ ctx->operation_succeeded = false;
-+ } else {
-+ /* DP 1.2a, table 2-58:
-+ * "S3: AUX Request CMD PENDING:
-+ * retry 3 times, with 400usec wait on each"
-+ * The HW timeout is set to 550usec,
-+ * so we should not wait here */
-+ }
-+ break;
-+ default:
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN;
-+ ctx->operation_succeeded = false;
-+ }
-+}
-+
-+static bool read_command(
-+ struct aux_engine *engine,
-+ struct i2caux_transaction_request *request,
-+ bool middle_of_transaction)
-+{
-+ struct read_command_context ctx;
-+
-+ ctx.buffer = request->payload.data;
-+ ctx.current_read_length = request->payload.length;
-+ ctx.offset = 0;
-+ ctx.timed_out_retry_aux = 0;
-+ ctx.invalid_reply_retry_aux = 0;
-+ ctx.defer_retry_aux = 0;
-+ ctx.defer_retry_i2c = 0;
-+ ctx.invalid_reply_retry_aux_on_ack = 0;
-+ ctx.transaction_complete = false;
-+ ctx.operation_succeeded = true;
-+
-+ if (request->payload.address_space ==
-+ I2CAUX_TRANSACTION_ADDRESS_SPACE_DPCD) {
-+ ctx.request.type = AUX_TRANSACTION_TYPE_DP;
-+ ctx.request.action = I2CAUX_TRANSACTION_ACTION_DP_READ;
-+ ctx.request.address = request->payload.address;
-+ } else if (request->payload.address_space ==
-+ I2CAUX_TRANSACTION_ADDRESS_SPACE_I2C) {
-+ ctx.request.type = AUX_TRANSACTION_TYPE_I2C;
-+ ctx.request.action = middle_of_transaction ?
-+ I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT :
-+ I2CAUX_TRANSACTION_ACTION_I2C_READ;
-+ ctx.request.address = request->payload.address >> 1;
-+ } else {
-+ /* in DAL2, there was no return in such case */
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ ctx.request.delay = 0;
-+
-+ do {
-+ dc_service_memset(ctx.buffer + ctx.offset, 0, ctx.current_read_length);
-+
-+ ctx.request.data = ctx.buffer + ctx.offset;
-+ ctx.request.length = ctx.current_read_length;
-+
-+ process_read_request(engine, &ctx);
-+
-+ request->status = ctx.status;
-+
-+ if (ctx.operation_succeeded && !ctx.transaction_complete)
-+ if (ctx.request.type == AUX_TRANSACTION_TYPE_I2C)
-+ dc_service_sleep_in_milliseconds(engine->base.ctx, engine->delay);
-+ } while (ctx.operation_succeeded && !ctx.transaction_complete);
-+
-+ return ctx.operation_succeeded;
-+}
-+
-+struct write_command_context {
-+ bool mot;
-+
-+ uint8_t *buffer;
-+ uint8_t current_write_length;
-+ enum i2caux_transaction_status status;
-+
-+ struct aux_request_transaction_data request;
-+ struct aux_reply_transaction_data reply;
-+
-+ uint8_t returned_byte;
-+
-+ uint32_t timed_out_retry_aux;
-+ uint32_t invalid_reply_retry_aux;
-+ uint32_t defer_retry_aux;
-+ uint32_t defer_retry_i2c;
-+ uint32_t max_defer_retry;
-+ uint32_t ack_m_retry;
-+
-+ uint8_t reply_data[DEFAULT_AUX_MAX_DATA_SIZE];
-+
-+ bool transaction_complete;
-+ bool operation_succeeded;
-+};
-+
-+static void process_write_reply(
-+ struct aux_engine *engine,
-+ struct write_command_context *ctx)
-+{
-+ engine->funcs->process_channel_reply(engine, &ctx->reply);
-+
-+ switch (ctx->reply.status) {
-+ case AUX_TRANSACTION_REPLY_AUX_ACK:
-+ ctx->operation_succeeded = true;
-+
-+ if (ctx->returned_byte) {
-+ ctx->request.action = ctx->mot ?
-+ I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST_MOT :
-+ I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST;
-+
-+ ctx->current_write_length = 0;
-+
-+ ++ctx->ack_m_retry;
-+
-+ if (ctx->ack_m_retry > AUX_DEFER_RETRY_COUNTER) {
-+ ctx->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT;
-+ ctx->operation_succeeded = false;
-+ } else
-+ dc_service_delay_in_microseconds(engine->base.ctx, 300);
-+ } else {
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_SUCCEEDED;
-+ ctx->defer_retry_aux = 0;
-+ ctx->ack_m_retry = 0;
-+ ctx->transaction_complete = true;
-+ }
-+ break;
-+ case AUX_TRANSACTION_REPLY_AUX_NACK:
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_NACK;
-+ ctx->operation_succeeded = false;
-+ break;
-+ case AUX_TRANSACTION_REPLY_AUX_DEFER:
-+ ++ctx->defer_retry_aux;
-+
-+ if (ctx->defer_retry_aux > ctx->max_defer_retry) {
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT;
-+ ctx->operation_succeeded = false;
-+ }
-+ break;
-+ case AUX_TRANSACTION_REPLY_I2C_DEFER:
-+ ctx->defer_retry_aux = 0;
-+ ctx->current_write_length = 0;
-+
-+ ctx->request.action = ctx->mot ?
-+ I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST_MOT :
-+ I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST;
-+
-+ ++ctx->defer_retry_i2c;
-+
-+ if (ctx->defer_retry_i2c > ctx->max_defer_retry) {
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT;
-+ ctx->operation_succeeded = false;
-+ }
-+ break;
-+ default:
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN;
-+ ctx->operation_succeeded = false;
-+ }
-+}
-+
-+static void process_write_request(
-+ struct aux_engine *engine,
-+ struct write_command_context *ctx)
-+{
-+ enum aux_channel_operation_result operation_result;
-+
-+ engine->funcs->submit_channel_request(engine, &ctx->request);
-+
-+ operation_result = engine->funcs->get_channel_status(
-+ engine, &ctx->returned_byte);
-+
-+ switch (operation_result) {
-+ case AUX_CHANNEL_OPERATION_SUCCEEDED:
-+ ctx->timed_out_retry_aux = 0;
-+ ctx->invalid_reply_retry_aux = 0;
-+
-+ ctx->reply.length = ctx->returned_byte;
-+ ctx->reply.data = ctx->reply_data;
-+
-+ process_write_reply(engine, ctx);
-+ break;
-+ case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY:
-+ ++ctx->invalid_reply_retry_aux;
-+
-+ if (ctx->invalid_reply_retry_aux >
-+ AUX_INVALID_REPLY_RETRY_COUNTER) {
-+ ctx->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR;
-+ ctx->operation_succeeded = false;
-+ } else
-+ dc_service_delay_in_microseconds(engine->base.ctx, 400);
-+ break;
-+ case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT:
-+ ++ctx->timed_out_retry_aux;
-+
-+ if (ctx->timed_out_retry_aux > AUX_TIMED_OUT_RETRY_COUNTER) {
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT;
-+ ctx->operation_succeeded = false;
-+ } else {
-+ /* DP 1.2a, table 2-58:
-+ * "S3: AUX Request CMD PENDING:
-+ * retry 3 times, with 400usec wait on each"
-+ * The HW timeout is set to 550usec,
-+ * so we should not wait here */
-+ }
-+ break;
-+ default:
-+ ctx->status = I2CAUX_TRANSACTION_STATUS_UNKNOWN;
-+ ctx->operation_succeeded = false;
-+ }
-+}
-+
-+static bool write_command(
-+ struct aux_engine *engine,
-+ struct i2caux_transaction_request *request,
-+ bool middle_of_transaction)
-+{
-+ struct write_command_context ctx;
-+
-+ ctx.mot = middle_of_transaction;
-+ ctx.buffer = request->payload.data;
-+ ctx.current_write_length = request->payload.length;
-+ ctx.timed_out_retry_aux = 0;
-+ ctx.invalid_reply_retry_aux = 0;
-+ ctx.defer_retry_aux = 0;
-+ ctx.defer_retry_i2c = 0;
-+ ctx.ack_m_retry = 0;
-+ ctx.transaction_complete = false;
-+ ctx.operation_succeeded = true;
-+
-+ if (request->payload.address_space ==
-+ I2CAUX_TRANSACTION_ADDRESS_SPACE_DPCD) {
-+ ctx.request.type = AUX_TRANSACTION_TYPE_DP;
-+ ctx.request.action = I2CAUX_TRANSACTION_ACTION_DP_WRITE;
-+ ctx.request.address = request->payload.address;
-+ } else if (request->payload.address_space ==
-+ I2CAUX_TRANSACTION_ADDRESS_SPACE_I2C) {
-+ ctx.request.type = AUX_TRANSACTION_TYPE_I2C;
-+ ctx.request.action = middle_of_transaction ?
-+ I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT :
-+ I2CAUX_TRANSACTION_ACTION_I2C_WRITE;
-+ ctx.request.address = request->payload.address >> 1;
-+ } else {
-+ /* in DAL2, there was no return in such case */
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ ctx.request.delay = 0;
-+
-+ ctx.max_defer_retry =
-+ (engine->max_defer_write_retry > AUX_DEFER_RETRY_COUNTER) ?
-+ engine->max_defer_write_retry : AUX_DEFER_RETRY_COUNTER;
-+
-+ do {
-+ ctx.request.data = ctx.buffer;
-+ ctx.request.length = ctx.current_write_length;
-+
-+ process_write_request(engine, &ctx);
-+
-+ request->status = ctx.status;
-+
-+ if (ctx.operation_succeeded && !ctx.transaction_complete)
-+ if (ctx.request.type == AUX_TRANSACTION_TYPE_I2C)
-+ dc_service_sleep_in_milliseconds(engine->base.ctx, engine->delay);
-+ } while (ctx.operation_succeeded && !ctx.transaction_complete);
-+
-+ return ctx.operation_succeeded;
-+}
-+
-+static bool end_of_transaction_command(
-+ struct aux_engine *engine,
-+ struct i2caux_transaction_request *request)
-+{
-+ struct i2caux_transaction_request dummy_request;
-+ uint8_t dummy_data;
-+
-+ /* [tcheng] We only need to send the stop (read with MOT = 0)
-+ * for I2C-over-Aux, not native AUX */
-+
-+ if (request->payload.address_space !=
-+ I2CAUX_TRANSACTION_ADDRESS_SPACE_I2C)
-+ return false;
-+
-+ dummy_request.operation = request->operation;
-+ dummy_request.payload.address_space = request->payload.address_space;
-+ dummy_request.payload.address = request->payload.address;
-+
-+ /*
-+ * Add a dummy byte due to some receiver quirk
-+ * where one byte is sent along with MOT = 0.
-+ * Ideally this should be 0.
-+ */
-+
-+ dummy_request.payload.length = 0;
-+ dummy_request.payload.data = &dummy_data;
-+
-+ if (request->operation == I2CAUX_TRANSACTION_READ)
-+ return read_command(engine, &dummy_request, false);
-+ else
-+ return write_command(engine, &dummy_request, false);
-+
-+ /* according Syed, it does not need now DoDummyMOT */
-+}
-+
-+bool dal_aux_engine_submit_request(
-+ struct engine *engine,
-+ struct i2caux_transaction_request *request,
-+ bool middle_of_transaction)
-+{
-+ struct aux_engine *aux_engine = FROM_ENGINE(engine);
-+
-+ bool result;
-+ bool mot_used = true;
-+
-+ switch (request->operation) {
-+ case I2CAUX_TRANSACTION_READ:
-+ result = read_command(aux_engine, request, mot_used);
-+ break;
-+ case I2CAUX_TRANSACTION_WRITE:
-+ result = write_command(aux_engine, request, mot_used);
-+ break;
-+ default:
-+ result = false;
-+ }
-+
-+ /* [tcheng]
-+ * need to send stop for the last transaction to free up the AUX
-+ * if the above command fails, this would be the last transaction */
-+
-+ if (!middle_of_transaction || !result)
-+ end_of_transaction_command(aux_engine, request);
-+
-+ /* mask AUX interrupt */
-+
-+ return result;
-+}
-+
-+bool dal_aux_engine_construct(
-+ struct aux_engine *engine,
-+ struct dc_context *ctx)
-+{
-+ if (!dal_i2caux_construct_engine(&engine->base, ctx))
-+ return false;
-+ engine->delay = 0;
-+ engine->max_defer_write_retry = 0;
-+ return true;
-+}
-+
-+void dal_aux_engine_destruct(
-+ struct aux_engine *engine)
-+{
-+ dal_i2caux_destruct_engine(&engine->base);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/aux_engine.h b/drivers/gpu/drm/amd/dal/dc/i2caux/aux_engine.h
-new file mode 100644
-index 0000000..474f5e9
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/aux_engine.h
-@@ -0,0 +1,119 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_AUX_ENGINE_H__
-+#define __DAL_AUX_ENGINE_H__
-+
-+enum aux_transaction_type {
-+ AUX_TRANSACTION_TYPE_DP,
-+ AUX_TRANSACTION_TYPE_I2C
-+};
-+
-+struct aux_request_transaction_data {
-+ enum aux_transaction_type type;
-+ enum i2caux_transaction_action action;
-+ /* 20-bit AUX channel transaction address */
-+ uint32_t address;
-+ /* delay, in 100-microsecond units */
-+ uint8_t delay;
-+ uint8_t length;
-+ uint8_t *data;
-+};
-+
-+enum aux_transaction_reply {
-+ AUX_TRANSACTION_REPLY_AUX_ACK = 0x00,
-+ AUX_TRANSACTION_REPLY_AUX_NACK = 0x01,
-+ AUX_TRANSACTION_REPLY_AUX_DEFER = 0x02,
-+
-+ AUX_TRANSACTION_REPLY_I2C_ACK = 0x00,
-+ AUX_TRANSACTION_REPLY_I2C_NACK = 0x10,
-+ AUX_TRANSACTION_REPLY_I2C_DEFER = 0x20,
-+
-+ AUX_TRANSACTION_REPLY_INVALID = 0xFF
-+};
-+
-+struct aux_reply_transaction_data {
-+ enum aux_transaction_reply status;
-+ uint8_t length;
-+ uint8_t *data;
-+};
-+
-+enum aux_channel_operation_result {
-+ AUX_CHANNEL_OPERATION_SUCCEEDED,
-+ AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN,
-+ AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY,
-+ AUX_CHANNEL_OPERATION_FAILED_TIMEOUT
-+};
-+
-+struct aux_engine;
-+
-+struct aux_engine_funcs {
-+ void (*destroy)(
-+ struct aux_engine **ptr);
-+ bool (*acquire_engine)(
-+ struct aux_engine *engine);
-+ void (*configure)(
-+ struct aux_engine *engine,
-+ union aux_config cfg);
-+ bool (*start_gtc_sync)(
-+ struct aux_engine *engine);
-+ void (*stop_gtc_sync)(
-+ struct aux_engine *engine);
-+ void (*submit_channel_request)(
-+ struct aux_engine *engine,
-+ struct aux_request_transaction_data *request);
-+ void (*process_channel_reply)(
-+ struct aux_engine *engine,
-+ struct aux_reply_transaction_data *reply);
-+ enum aux_channel_operation_result (*get_channel_status)(
-+ struct aux_engine *engine,
-+ uint8_t *returned_bytes);
-+};
-+
-+struct aux_engine {
-+ struct engine base;
-+ const struct aux_engine_funcs *funcs;
-+ /* following values are expressed in milliseconds */
-+ uint32_t delay;
-+ uint32_t max_defer_write_retry;
-+};
-+
-+bool dal_aux_engine_construct(
-+ struct aux_engine *engine,
-+ struct dc_context *ctx);
-+
-+void dal_aux_engine_destruct(
-+ struct aux_engine *engine);
-+bool dal_aux_engine_submit_request(
-+ struct engine *ptr,
-+ struct i2caux_transaction_request *request,
-+ bool middle_of_transaction);
-+bool dal_aux_engine_acquire(
-+ struct engine *ptr,
-+ struct ddc *ddc);
-+enum i2caux_engine_type dal_aux_engine_get_engine_type(
-+ const struct engine *engine);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/aux_engine_dce110.c b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/aux_engine_dce110.c
-new file mode 100644
-index 0000000..1b40a78
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/aux_engine_dce110.c
-@@ -0,0 +1,789 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/i2caux_interface.h"
-+#include "../engine.h"
-+#include "../aux_engine.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "aux_engine_dce110.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+/*
-+ * This unit
-+ */
-+
-+/*
-+ * @brief
-+ * Cast 'struct aux_engine *'
-+ * to 'struct aux_engine_dce110 *'
-+ */
-+#define FROM_AUX_ENGINE(ptr) \
-+ container_of((ptr), struct aux_engine_dce110, base)
-+
-+/*
-+ * @brief
-+ * Cast 'struct engine *'
-+ * to 'struct aux_engine_dce110 *'
-+ */
-+#define FROM_ENGINE(ptr) \
-+ FROM_AUX_ENGINE(container_of((ptr), struct aux_engine, base))
-+
-+static void release_engine(
-+ struct engine *engine)
-+{
-+ struct aux_engine_dce110 *aux_engine = FROM_ENGINE(engine);
-+
-+ const uint32_t addr = aux_engine->addr.aux_arb_control;
-+
-+ uint32_t value = dal_read_reg(engine->ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_ARB_CONTROL,
-+ AUX_SW_DONE_USING_AUX_REG);
-+
-+ dal_write_reg(engine->ctx, addr, value);
-+}
-+
-+static void destruct(
-+ struct aux_engine_dce110 *engine);
-+
-+static void destroy(
-+ struct aux_engine **aux_engine)
-+{
-+ struct aux_engine_dce110 *engine = FROM_AUX_ENGINE(*aux_engine);
-+
-+ destruct(engine);
-+
-+ dc_service_free((*aux_engine)->base.ctx, engine);
-+
-+ *aux_engine = NULL;
-+}
-+
-+#define SW_CAN_ACCESS_AUX 1
-+
-+static bool acquire_engine(
-+ struct aux_engine *engine)
-+{
-+ struct aux_engine_dce110 *aux_engine = FROM_AUX_ENGINE(engine);
-+ uint32_t value;
-+ uint32_t field;
-+
-+ /* enable AUX before request SW to access AUX */
-+ {
-+ const uint32_t addr = aux_engine->addr.aux_control;
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ field = get_reg_field_value(
-+ value,
-+ AUX_CONTROL,
-+ AUX_EN);
-+
-+ if (field == 0) {
-+ uint8_t counter = 0;
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_CONTROL,
-+ AUX_EN);
-+
-+ /*DP_AUX block as part of the enable sequence*/
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_CONTROL,
-+ AUX_RESET);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+
-+ /*poll HW to make sure reset it done*/
-+ do {
-+ dc_service_delay_in_microseconds(engine->base.ctx, 1);
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ field = get_reg_field_value(
-+ value,
-+ AUX_CONTROL,
-+ AUX_RESET_DONE);
-+
-+ counter++;
-+
-+ } while ((field == 0) && (counter < 11));
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUX_CONTROL,
-+ AUX_RESET);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+
-+ counter = 0;
-+
-+ do {
-+ dc_service_delay_in_microseconds(engine->base.ctx, 1);
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ field = get_reg_field_value(
-+ value,
-+ AUX_CONTROL,
-+ AUX_RESET_DONE);
-+
-+ counter++;
-+
-+ } while ((field == 1) && (counter < 11));
-+ } /*if (field)*/
-+ }
-+
-+ /* request SW to access AUX */
-+ {
-+ const uint32_t addr = aux_engine->addr.aux_arb_control;
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_ARB_CONTROL,
-+ AUX_SW_USE_AUX_REG_REQ);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ field = get_reg_field_value(
-+ value,
-+ AUX_ARB_CONTROL,
-+ AUX_REG_RW_CNTL_STATUS);
-+
-+ return field == SW_CAN_ACCESS_AUX;
-+ }
-+}
-+
-+static void configure(
-+ struct aux_engine *engine,
-+ union aux_config cfg)
-+{
-+ struct aux_engine_dce110 *aux_engine = FROM_AUX_ENGINE(engine);
-+
-+ const uint32_t addr = aux_engine->addr.aux_control;
-+
-+ uint32_t value = dal_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ (0 != cfg.bits.ALLOW_AUX_WHEN_HPD_LOW),
-+ AUX_CONTROL,
-+ AUX_IGNORE_HPD_DISCON);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+}
-+
-+static bool start_gtc_sync(
-+ struct aux_engine *engine)
-+{
-+ /*TODO*/
-+ return false;
-+}
-+
-+static void stop_gtc_sync(
-+ struct aux_engine *engine)
-+{
-+ /*TODO*/
-+}
-+
-+#define COMPOSE_AUX_SW_DATA_16_20(command, address) \
-+ ((command) | ((0xF0000 & (address)) >> 16))
-+
-+#define COMPOSE_AUX_SW_DATA_8_15(address) \
-+ ((0xFF00 & (address)) >> 8)
-+
-+#define COMPOSE_AUX_SW_DATA_0_7(address) \
-+ (0xFF & (address))
-+
-+static void submit_channel_request(
-+ struct aux_engine *engine,
-+ struct aux_request_transaction_data *request)
-+{
-+ struct aux_engine_dce110 *aux_engine = FROM_AUX_ENGINE(engine);
-+ uint32_t value;
-+ uint32_t length;
-+
-+ bool is_write =
-+ ((request->type == AUX_TRANSACTION_TYPE_DP) &&
-+ (request->action == I2CAUX_TRANSACTION_ACTION_DP_WRITE)) ||
-+ ((request->type == AUX_TRANSACTION_TYPE_I2C) &&
-+ ((request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE) ||
-+ (request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT)));
-+
-+ /* clear_aux_error */
-+ {
-+ const uint32_t addr = mmAUXN_IMPCAL;
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUXN_IMPCAL,
-+ AUXN_CALOUT_ERROR_AK);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUXN_IMPCAL,
-+ AUXN_CALOUT_ERROR_AK);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+ }
-+ {
-+ const uint32_t addr = mmAUXP_IMPCAL;
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUXP_IMPCAL,
-+ AUXP_CALOUT_ERROR_AK);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUXP_IMPCAL,
-+ AUXP_CALOUT_ERROR_AK);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+ }
-+
-+ /* force_default_calibrate */
-+ {
-+ const uint32_t addr = mmAUXN_IMPCAL;
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUXN_IMPCAL,
-+ AUXN_IMPCAL_ENABLE);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUXN_IMPCAL,
-+ AUXN_IMPCAL_OVERRIDE_ENABLE);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+ }
-+ {
-+ const uint32_t addr = mmAUXP_IMPCAL;
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUXP_IMPCAL,
-+ AUXP_IMPCAL_OVERRIDE_ENABLE);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUXP_IMPCAL,
-+ AUXP_IMPCAL_OVERRIDE_ENABLE);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+ }
-+
-+ /* set the delay and the number of bytes to write */
-+ {
-+ const uint32_t addr = aux_engine->addr.aux_sw_control;
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ request->delay,
-+ AUX_SW_CONTROL,
-+ AUX_SW_START_DELAY);
-+
-+ /* The length include
-+ * the 4 bit header and the 20 bit address
-+ * (that is 3 byte).
-+ * If the requested length is non zero this means
-+ * an addition byte specifying the length is required. */
-+
-+ length = request->length ? 4 : 3;
-+ if (is_write)
-+ length += request->length;
-+
-+ set_reg_field_value(
-+ value,
-+ length,
-+ AUX_SW_CONTROL,
-+ AUX_SW_WR_BYTES);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+ }
-+
-+ /* program action and address and payload data (if 'is_write') */
-+ {
-+ const uint32_t addr = aux_engine->addr.aux_sw_data;
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUX_SW_DATA,
-+ AUX_SW_INDEX);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUX_SW_DATA,
-+ AUX_SW_DATA_RW);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_SW_DATA,
-+ AUX_SW_AUTOINCREMENT_DISABLE);
-+
-+ set_reg_field_value(
-+ value,
-+ COMPOSE_AUX_SW_DATA_16_20(
-+ request->action, request->address),
-+ AUX_SW_DATA,
-+ AUX_SW_DATA);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUX_SW_DATA,
-+ AUX_SW_AUTOINCREMENT_DISABLE);
-+
-+ set_reg_field_value(
-+ value,
-+ COMPOSE_AUX_SW_DATA_8_15(request->address),
-+ AUX_SW_DATA,
-+ AUX_SW_DATA);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ COMPOSE_AUX_SW_DATA_0_7(request->address),
-+ AUX_SW_DATA,
-+ AUX_SW_DATA);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+
-+ if (request->length) {
-+ set_reg_field_value(
-+ value,
-+ request->length - 1,
-+ AUX_SW_DATA,
-+ AUX_SW_DATA);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+ }
-+
-+ if (is_write) {
-+ /* Load the HW buffer with the Data to be sent.
-+ * This is relevant for write operation.
-+ * For read, the data recived data will be
-+ * processed in process_channel_reply(). */
-+ uint32_t i = 0;
-+
-+ while (i < request->length) {
-+
-+ set_reg_field_value(
-+ value,
-+ request->data[i],
-+ AUX_SW_DATA,
-+ AUX_SW_DATA);
-+
-+ dal_write_reg(
-+ engine->base.ctx, addr, value);
-+
-+ ++i;
-+ }
-+ }
-+ }
-+
-+ {
-+ const uint32_t addr = aux_engine->addr.aux_interrupt_control;
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_INTERRUPT_CONTROL,
-+ AUX_SW_DONE_ACK);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+ }
-+
-+ {
-+ const uint32_t addr = aux_engine->addr.aux_sw_control;
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_SW_CONTROL,
-+ AUX_SW_GO);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+ }
-+}
-+
-+static void process_channel_reply(
-+ struct aux_engine *engine,
-+ struct aux_reply_transaction_data *reply)
-+{
-+ struct aux_engine_dce110 *aux_engine = FROM_AUX_ENGINE(engine);
-+
-+ /* Need to do a read to get the number of bytes to process
-+ * Alternatively, this information can be passed -
-+ * but that causes coupling which isn't good either. */
-+
-+ uint32_t bytes_replied;
-+ uint32_t value;
-+
-+ {
-+ const uint32_t addr = aux_engine->addr.aux_sw_status;
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ bytes_replied = get_reg_field_value(
-+ value,
-+ AUX_SW_STATUS,
-+ AUX_SW_REPLY_BYTE_COUNT);
-+ }
-+
-+ if (bytes_replied) {
-+ uint32_t reply_result;
-+
-+ const uint32_t addr = aux_engine->addr.aux_sw_data;
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUX_SW_DATA,
-+ AUX_SW_INDEX);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_SW_DATA,
-+ AUX_SW_AUTOINCREMENT_DISABLE);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_SW_DATA,
-+ AUX_SW_DATA_RW);
-+
-+ dal_write_reg(engine->base.ctx, addr, value);
-+
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ reply_result = get_reg_field_value(
-+ value,
-+ AUX_SW_DATA,
-+ AUX_SW_DATA);
-+
-+ reply_result = reply_result >> 4;
-+
-+ switch (reply_result) {
-+ case 0: /* ACK */ {
-+ uint32_t i = 0;
-+
-+ /* first byte was already used
-+ * to get the command status */
-+ --bytes_replied;
-+
-+ while (i < bytes_replied) {
-+ value = dal_read_reg(
-+ engine->base.ctx, addr);
-+
-+ reply->data[i] = get_reg_field_value(
-+ value,
-+ AUX_SW_DATA,
-+ AUX_SW_DATA);
-+
-+ ++i;
-+ }
-+
-+ reply->status = AUX_TRANSACTION_REPLY_AUX_ACK;
-+ }
-+ break;
-+ case 1: /* NACK */
-+ reply->status = AUX_TRANSACTION_REPLY_AUX_NACK;
-+ break;
-+ case 2: /* DEFER */
-+ reply->status = AUX_TRANSACTION_REPLY_AUX_DEFER;
-+ break;
-+ case 4: /* AUX ACK / I2C NACK */
-+ reply->status = AUX_TRANSACTION_REPLY_I2C_NACK;
-+ break;
-+ case 8: /* AUX ACK / I2C DEFER */
-+ reply->status = AUX_TRANSACTION_REPLY_I2C_DEFER;
-+ break;
-+ default:
-+ reply->status = AUX_TRANSACTION_REPLY_INVALID;
-+ }
-+ } else {
-+ /* Need to handle an error case...
-+ * hopefully, upper layer function won't call this function
-+ * if the number of bytes in the reply was 0
-+ * because there was surely an error that was asserted
-+ * that should have been handled
-+ * for hot plug case, this could happens*/
-+ if (!(value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK))
-+ ASSERT_CRITICAL(false);
-+ }
-+}
-+
-+static enum aux_channel_operation_result get_channel_status(
-+ struct aux_engine *engine,
-+ uint8_t *returned_bytes)
-+{
-+ struct aux_engine_dce110 *aux_engine = FROM_AUX_ENGINE(engine);
-+
-+ const uint32_t addr = aux_engine->addr.aux_sw_status;
-+
-+ uint32_t value;
-+ uint32_t aux_sw_done;
-+
-+ if (returned_bytes == NULL) {
-+ /*caller pass NULL pointer*/
-+ ASSERT_CRITICAL(false);
-+ return AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN;
-+ }
-+ *returned_bytes = 0;
-+
-+ /* poll to make sure that SW_DONE is asserted */
-+ {
-+ uint32_t time_elapsed = 0;
-+
-+ do {
-+ value = dal_read_reg(engine->base.ctx, addr);
-+
-+ aux_sw_done = get_reg_field_value(
-+ value,
-+ AUX_SW_STATUS,
-+ AUX_SW_DONE);
-+
-+ if (aux_sw_done)
-+ break;
-+
-+ dc_service_delay_in_microseconds(engine->base.ctx, 10);
-+
-+ time_elapsed += 10;
-+ } while (time_elapsed < aux_engine->timeout_period);
-+
-+
-+ }
-+
-+ /* Note that the following bits are set in 'status.bits'
-+ * during CTS 4.2.1.2:
-+ * AUX_SW_RX_MIN_COUNT_VIOL, AUX_SW_RX_INVALID_STOP,
-+ * AUX_SW_RX_RECV_NO_DET, AUX_SW_RX_RECV_INVALID_H.
-+ *
-+ * AUX_SW_RX_MIN_COUNT_VIOL is an internal,
-+ * HW debugging bit and should be ignored. */
-+ if (aux_sw_done) {
-+ if (get_reg_field_value(
-+ value,
-+ AUX_SW_STATUS,
-+ AUX_SW_RX_TIMEOUT_STATE) ||
-+ get_reg_field_value(
-+ value,
-+ AUX_SW_STATUS,
-+ AUX_SW_RX_TIMEOUT))
-+ return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT;
-+ else if (get_reg_field_value(
-+ value,
-+ AUX_SW_STATUS,
-+ AUX_SW_RX_INVALID_STOP))
-+ return AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY;
-+
-+ *returned_bytes = get_reg_field_value(
-+ value,
-+ AUX_SW_STATUS,
-+ AUX_SW_REPLY_BYTE_COUNT);
-+ if (*returned_bytes == 0)
-+ return
-+ AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY;
-+ else {
-+ *returned_bytes -= 1;
-+ return AUX_CHANNEL_OPERATION_SUCCEEDED;
-+ }
-+ } else {
-+ /*time_elapsed >= aux_engine->timeout_period */
-+ if (!(value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK))
-+ ASSERT_CRITICAL(false);
-+ return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT;
-+ }
-+}
-+
-+static const int32_t aux_channel_offset[] = {
-+ mmDP_AUX0_AUX_CONTROL - mmDP_AUX0_AUX_CONTROL,
-+ mmDP_AUX1_AUX_CONTROL - mmDP_AUX0_AUX_CONTROL,
-+ mmDP_AUX2_AUX_CONTROL - mmDP_AUX0_AUX_CONTROL,
-+ mmDP_AUX3_AUX_CONTROL - mmDP_AUX0_AUX_CONTROL,
-+ mmDP_AUX4_AUX_CONTROL - mmDP_AUX0_AUX_CONTROL,
-+ mmDP_AUX5_AUX_CONTROL - mmDP_AUX0_AUX_CONTROL
-+};
-+
-+static const struct aux_engine_funcs aux_engine_funcs = {
-+ .destroy = destroy,
-+ .acquire_engine = acquire_engine,
-+ .configure = configure,
-+ .start_gtc_sync = start_gtc_sync,
-+ .stop_gtc_sync = stop_gtc_sync,
-+ .submit_channel_request = submit_channel_request,
-+ .process_channel_reply = process_channel_reply,
-+ .get_channel_status = get_channel_status,
-+};
-+
-+static const struct engine_funcs engine_funcs = {
-+ .release_engine = release_engine,
-+ .submit_request = dal_aux_engine_submit_request,
-+ .keep_power_up_count = dal_i2caux_keep_power_up_count,
-+ .get_engine_type = dal_aux_engine_get_engine_type,
-+ .acquire = dal_aux_engine_acquire,
-+};
-+
-+static bool construct(
-+ struct aux_engine_dce110 *engine,
-+ const struct aux_engine_dce110_init_data *aux_init_data)
-+{
-+ int32_t offset;
-+
-+ if (aux_init_data->engine_id >=
-+ sizeof(aux_channel_offset) / sizeof(int32_t)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ if (!dal_aux_engine_construct(
-+ &engine->base, aux_init_data->ctx)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+ engine->base.base.funcs = &engine_funcs;
-+ engine->base.funcs = &aux_engine_funcs;
-+ offset = aux_channel_offset[aux_init_data->engine_id];
-+ engine->addr.aux_control = mmAUX_CONTROL + offset;
-+ engine->addr.aux_arb_control = mmAUX_ARB_CONTROL + offset;
-+ engine->addr.aux_sw_data = mmAUX_SW_DATA + offset;
-+ engine->addr.aux_sw_control = mmAUX_SW_CONTROL + offset;
-+ engine->addr.aux_interrupt_control = mmAUX_INTERRUPT_CONTROL + offset;
-+ engine->addr.aux_sw_status = mmAUX_SW_STATUS + offset;
-+ engine->addr.aux_gtc_sync_control = mmAUX_GTC_SYNC_CONTROL + offset;
-+ engine->addr.aux_gtc_sync_status = mmAUX_GTC_SYNC_STATUS + offset;
-+ engine->addr.aux_gtc_sync_controller_status =
-+ mmAUX_GTC_SYNC_CONTROLLER_STATUS + offset;
-+
-+ engine->timeout_period = aux_init_data->timeout_period;
-+
-+ return true;
-+}
-+
-+static void destruct(
-+ struct aux_engine_dce110 *engine)
-+{
-+ dal_aux_engine_destruct(&engine->base);
-+}
-+
-+struct aux_engine *dal_aux_engine_dce110_create(
-+ const struct aux_engine_dce110_init_data *aux_init_data)
-+{
-+ struct aux_engine_dce110 *engine;
-+
-+ if (!aux_init_data) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ engine = dc_service_alloc(aux_init_data->ctx, sizeof(*engine));
-+
-+ if (!engine) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ if (construct(engine, aux_init_data))
-+ return &engine->base;
-+
-+ ASSERT_CRITICAL(false);
-+
-+ dc_service_free(aux_init_data->ctx, engine);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/aux_engine_dce110.h b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/aux_engine_dce110.h
-new file mode 100644
-index 0000000..ec6899e
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/aux_engine_dce110.h
-@@ -0,0 +1,56 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_AUX_ENGINE_DCE110_H__
-+#define __DAL_AUX_ENGINE_DCE110_H__
-+
-+#include "../aux_engine.h"
-+
-+struct aux_engine_dce110 {
-+ struct aux_engine base;
-+ struct {
-+ uint32_t aux_control;
-+ uint32_t aux_arb_control;
-+ uint32_t aux_sw_data;
-+ uint32_t aux_sw_control;
-+ uint32_t aux_interrupt_control;
-+ uint32_t aux_sw_status;
-+ uint32_t aux_gtc_sync_control;
-+ uint32_t aux_gtc_sync_status;
-+ uint32_t aux_gtc_sync_controller_status;
-+ } addr;
-+ uint32_t timeout_period;
-+};
-+
-+struct aux_engine_dce110_init_data {
-+ uint32_t engine_id;
-+ uint32_t timeout_period;
-+ struct dc_context *ctx;
-+};
-+
-+struct aux_engine *dal_aux_engine_dce110_create(
-+ const struct aux_engine_dce110_init_data *aux_init_data);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_generic_hw_engine_dce110.h b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_generic_hw_engine_dce110.h
-new file mode 100644
-index 0000000..e6b6a97
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_generic_hw_engine_dce110.h
-@@ -0,0 +1,25 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.c b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.c
-new file mode 100644
-index 0000000..17e89ce
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.c
-@@ -0,0 +1,954 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+#include "include/logger_interface.h"
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/i2caux_interface.h"
-+#include "../engine.h"
-+#include "../i2c_engine.h"
-+#include "../i2c_hw_engine.h"
-+#include "../i2c_generic_hw_engine.h"
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "i2c_hw_engine_dce110.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+
-+/*
-+ * This unit
-+ */
-+
-+enum dc_i2c_status {
-+ DC_I2C_STATUS__DC_I2C_STATUS_IDLE,
-+ DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_SW,
-+ DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_HW
-+};
-+
-+enum dc_i2c_arbitration {
-+ DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_NORMAL,
-+ DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_HIGH
-+};
-+
-+enum {
-+ /* No timeout in HW
-+ * (timeout implemented in SW by querying status) */
-+ I2C_SETUP_TIME_LIMIT = 255,
-+ I2C_HW_BUFFER_SIZE = 144
-+};
-+
-+/*
-+ * @brief
-+ * Cast pointer to 'struct i2c_hw_engine *'
-+ * to pointer 'struct i2c_hw_engine_dce110 *'
-+ */
-+#define FROM_I2C_HW_ENGINE(ptr) \
-+ container_of((ptr), struct i2c_hw_engine_dce110, base)
-+/*
-+ * @brief
-+ * Cast pointer to 'struct i2c_engine *'
-+ * to pointer to 'struct i2c_hw_engine_dce110 *'
-+ */
-+#define FROM_I2C_ENGINE(ptr) \
-+ FROM_I2C_HW_ENGINE(container_of((ptr), struct i2c_hw_engine, base))
-+
-+/*
-+ * @brief
-+ * Cast pointer to 'struct engine *'
-+ * to 'pointer to struct i2c_hw_engine_dce110 *'
-+ */
-+#define FROM_ENGINE(ptr) \
-+ FROM_I2C_ENGINE(container_of((ptr), struct i2c_engine, base))
-+
-+
-+static void disable_i2c_hw_engine(
-+ struct i2c_hw_engine_dce110 *engine)
-+{
-+ const uint32_t addr = engine->addr.DC_I2C_DDCX_SETUP;
-+ uint32_t value = 0;
-+
-+ struct dc_context *ctx = NULL;
-+
-+ ctx = engine->base.base.base.ctx;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_DDC1_SETUP,
-+ DC_I2C_DDC1_ENABLE);
-+
-+ dal_write_reg(ctx, addr, value);
-+}
-+
-+static void release_engine(
-+ struct engine *engine)
-+{
-+ struct i2c_hw_engine_dce110 *hw_engine = FROM_ENGINE(engine);
-+
-+ struct i2c_engine *base = NULL;
-+ bool safe_to_reset;
-+ uint32_t value = 0;
-+
-+ base = &hw_engine->base.base;
-+
-+ /* Restore original HW engine speed */
-+
-+ base->funcs->set_speed(base, hw_engine->base.original_speed);
-+
-+ /* Release I2C */
-+ {
-+ value = dal_read_reg(engine->ctx, mmDC_I2C_ARBITRATION);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_ARBITRATION,
-+ DC_I2C_SW_DONE_USING_I2C_REG);
-+
-+ dal_write_reg(engine->ctx, mmDC_I2C_ARBITRATION, value);
-+ }
-+
-+ /* Reset HW engine */
-+ {
-+ uint32_t i2c_sw_status = 0;
-+
-+ value = dal_read_reg(engine->ctx, mmDC_I2C_SW_STATUS);
-+
-+ i2c_sw_status = get_reg_field_value(
-+ value,
-+ DC_I2C_SW_STATUS,
-+ DC_I2C_SW_STATUS);
-+ /* if used by SW, safe to reset */
-+ safe_to_reset = (i2c_sw_status == 1);
-+ }
-+ {
-+ value = dal_read_reg(engine->ctx, mmDC_I2C_CONTROL);
-+
-+ if (safe_to_reset)
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_CONTROL,
-+ DC_I2C_SOFT_RESET);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_CONTROL,
-+ DC_I2C_SW_STATUS_RESET);
-+
-+ dal_write_reg(engine->ctx, mmDC_I2C_CONTROL, value);
-+ }
-+
-+ /* HW I2c engine - clock gating feature */
-+ if (!hw_engine->engine_keep_power_up_count)
-+ disable_i2c_hw_engine(hw_engine);
-+}
-+
-+static void keep_power_up_count(
-+ struct engine *engine,
-+ bool keep_power_up)
-+{
-+ struct i2c_hw_engine_dce110 *hw_engine = FROM_ENGINE(engine);
-+
-+ if (keep_power_up)
-+ ++hw_engine->engine_keep_power_up_count;
-+ else {
-+ --hw_engine->engine_keep_power_up_count;
-+
-+ if (!hw_engine->engine_keep_power_up_count)
-+ disable_i2c_hw_engine(hw_engine);
-+ }
-+}
-+
-+static bool setup_engine(
-+ struct i2c_engine *i2c_engine)
-+{
-+ uint32_t value = 0;
-+ struct i2c_hw_engine_dce110 *engine = FROM_I2C_ENGINE(i2c_engine);
-+
-+ /* Program pin select */
-+ {
-+ const uint32_t addr = mmDC_I2C_CONTROL;
-+
-+ value = dal_read_reg(i2c_engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_CONTROL,
-+ DC_I2C_GO);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_CONTROL,
-+ DC_I2C_SOFT_RESET);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_CONTROL,
-+ DC_I2C_SEND_RESET);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_CONTROL,
-+ DC_I2C_SW_STATUS_RESET);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_CONTROL,
-+ DC_I2C_TRANSACTION_COUNT);
-+
-+ set_reg_field_value(
-+ value,
-+ engine->engine_id,
-+ DC_I2C_CONTROL,
-+ DC_I2C_DDC_SELECT);
-+
-+
-+ dal_write_reg(i2c_engine->base.ctx, addr, value);
-+ }
-+
-+ /* Program time limit */
-+ {
-+ const uint32_t addr = engine->addr.DC_I2C_DDCX_SETUP;
-+
-+ value = dal_read_reg(i2c_engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ I2C_SETUP_TIME_LIMIT,
-+ DC_I2C_DDC1_SETUP,
-+ DC_I2C_DDC1_TIME_LIMIT);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_DDC1_SETUP,
-+ DC_I2C_DDC1_ENABLE);
-+
-+ dal_write_reg(i2c_engine->base.ctx, addr, value);
-+ }
-+
-+ /* Program HW priority
-+ * set to High - interrupt software I2C at any time
-+ * Enable restart of SW I2C that was interrupted by HW
-+ * disable queuing of software while I2C is in use by HW */
-+ {
-+ value = dal_read_reg(i2c_engine->base.ctx,
-+ mmDC_I2C_ARBITRATION);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_ARBITRATION,
-+ DC_I2C_NO_QUEUED_SW_GO);
-+
-+ set_reg_field_value(
-+ value,
-+ DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_NORMAL,
-+ DC_I2C_ARBITRATION,
-+ DC_I2C_SW_PRIORITY);
-+
-+ dal_write_reg(i2c_engine->base.ctx,
-+ mmDC_I2C_ARBITRATION, value);
-+ }
-+
-+ return true;
-+}
-+
-+static uint32_t get_speed(
-+ const struct i2c_engine *i2c_engine)
-+{
-+ const struct i2c_hw_engine_dce110 *engine = FROM_I2C_ENGINE(i2c_engine);
-+
-+ const uint32_t addr = engine->addr.DC_I2C_DDCX_SPEED;
-+
-+ uint32_t pre_scale = 0;
-+
-+ uint32_t value = dal_read_reg(i2c_engine->base.ctx, addr);
-+
-+ pre_scale = get_reg_field_value(
-+ value,
-+ DC_I2C_DDC1_SPEED,
-+ DC_I2C_DDC1_PRESCALE);
-+
-+ /* [anaumov] it seems following is unnecessary */
-+ /*ASSERT(value.bits.DC_I2C_DDC1_PRESCALE);*/
-+
-+ return pre_scale ?
-+ engine->reference_frequency / pre_scale :
-+ engine->base.default_speed;
-+}
-+
-+static void set_speed(
-+ struct i2c_engine *i2c_engine,
-+ uint32_t speed)
-+{
-+ struct i2c_hw_engine_dce110 *engine = FROM_I2C_ENGINE(i2c_engine);
-+
-+ if (speed) {
-+ const uint32_t addr = engine->addr.DC_I2C_DDCX_SPEED;
-+
-+ uint32_t value = dal_read_reg(i2c_engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ engine->reference_frequency / speed,
-+ DC_I2C_DDC1_SPEED,
-+ DC_I2C_DDC1_PRESCALE);
-+
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ DC_I2C_DDC1_SPEED,
-+ DC_I2C_DDC1_THRESHOLD);
-+
-+ /*DCE11, HW add 100Khz support for I2c*/
-+ if (speed > 50) {
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ DC_I2C_DDC1_SPEED,
-+ DC_I2C_DDC1_START_STOP_TIMING_CNTL);
-+ } else {
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_DDC1_SPEED,
-+ DC_I2C_DDC1_START_STOP_TIMING_CNTL);
-+ }
-+
-+ dal_write_reg(i2c_engine->base.ctx, addr, value);
-+ }
-+}
-+
-+static inline void reset_hw_engine(struct engine *engine)
-+{
-+ uint32_t value = dal_read_reg(engine->ctx, mmDC_I2C_CONTROL);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_CONTROL,
-+ DC_I2C_SOFT_RESET);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_CONTROL,
-+ DC_I2C_SW_STATUS_RESET);
-+
-+ dal_write_reg(engine->ctx, mmDC_I2C_CONTROL, value);
-+}
-+
-+static bool is_hw_busy(struct engine *engine)
-+{
-+ uint32_t i2c_sw_status = 0;
-+
-+ uint32_t value = dal_read_reg(engine->ctx, mmDC_I2C_SW_STATUS);
-+
-+ i2c_sw_status = get_reg_field_value(
-+ value,
-+ DC_I2C_SW_STATUS,
-+ DC_I2C_SW_STATUS);
-+
-+ if (i2c_sw_status == DC_I2C_STATUS__DC_I2C_STATUS_IDLE)
-+ return false;
-+
-+ reset_hw_engine(engine);
-+
-+ value = dal_read_reg(engine->ctx, mmDC_I2C_SW_STATUS);
-+
-+ i2c_sw_status = get_reg_field_value(
-+ value,
-+ DC_I2C_SW_STATUS,
-+ DC_I2C_SW_STATUS);
-+
-+ return i2c_sw_status != DC_I2C_STATUS__DC_I2C_STATUS_IDLE;
-+}
-+
-+/*
-+ * @brief
-+ * DC_GPIO_DDC MM register offsets
-+ */
-+static const uint32_t transaction_addr[] = {
-+ mmDC_I2C_TRANSACTION0,
-+ mmDC_I2C_TRANSACTION1,
-+ mmDC_I2C_TRANSACTION2,
-+ mmDC_I2C_TRANSACTION3
-+};
-+
-+static bool process_transaction(
-+ struct i2c_hw_engine_dce110 *engine,
-+ struct i2c_request_transaction_data *request)
-+{
-+ uint8_t length = request->length;
-+ uint8_t *buffer = request->data;
-+
-+ bool last_transaction = false;
-+ uint32_t value = 0;
-+
-+ struct dc_context *ctx = NULL;
-+
-+ ctx = engine->base.base.base.ctx;
-+
-+ {
-+ const uint32_t addr =
-+ transaction_addr[engine->transaction_count];
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_TRANSACTION0,
-+ DC_I2C_STOP_ON_NACK0);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_TRANSACTION0,
-+ DC_I2C_START0);
-+
-+
-+ if ((engine->transaction_count == 3) ||
-+ (request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE) ||
-+ (request->action & I2CAUX_TRANSACTION_ACTION_I2C_READ)) {
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_TRANSACTION0,
-+ DC_I2C_STOP0);
-+
-+ last_transaction = true;
-+ } else
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_TRANSACTION0,
-+ DC_I2C_STOP0);
-+
-+ set_reg_field_value(
-+ value,
-+ (0 != (request->action &
-+ I2CAUX_TRANSACTION_ACTION_I2C_READ)),
-+ DC_I2C_TRANSACTION0,
-+ DC_I2C_RW0);
-+
-+ set_reg_field_value(
-+ value,
-+ length,
-+ DC_I2C_TRANSACTION0,
-+ DC_I2C_COUNT0);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+
-+ /* Write the I2C address and I2C data
-+ * into the hardware circular buffer, one byte per entry.
-+ * As an example, the 7-bit I2C slave address for CRT monitor
-+ * for reading DDC/EDID information is 0b1010001.
-+ * For an I2C send operation, the LSB must be programmed to 0;
-+ * for I2C receive operation, the LSB must be programmed to 1. */
-+
-+ {
-+ value = 0;
-+
-+ set_reg_field_value(
-+ value,
-+ false,
-+ DC_I2C_DATA,
-+ DC_I2C_DATA_RW);
-+
-+ set_reg_field_value(
-+ value,
-+ request->address,
-+ DC_I2C_DATA,
-+ DC_I2C_DATA);
-+
-+ if (engine->transaction_count == 0) {
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_DATA,
-+ DC_I2C_INDEX);
-+
-+ /*enable index write*/
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_DATA,
-+ DC_I2C_INDEX_WRITE);
-+
-+ engine->buffer_used_write = 0;
-+ }
-+
-+ dal_write_reg(ctx, mmDC_I2C_DATA, value);
-+
-+ engine->buffer_used_write++;
-+
-+ if (!(request->action & I2CAUX_TRANSACTION_ACTION_I2C_READ)) {
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_DATA,
-+ DC_I2C_INDEX_WRITE);
-+
-+ while (length) {
-+
-+ set_reg_field_value(
-+ value,
-+ *buffer++,
-+ DC_I2C_DATA,
-+ DC_I2C_DATA);
-+
-+ dal_write_reg(ctx, mmDC_I2C_DATA, value);
-+
-+ engine->buffer_used_write++;
-+ --length;
-+ }
-+ }
-+ }
-+
-+ ++engine->transaction_count;
-+ engine->buffer_used_bytes += length + 1;
-+
-+ return last_transaction;
-+}
-+
-+static void execute_transaction(
-+ struct i2c_hw_engine_dce110 *engine)
-+{
-+ uint32_t value = 0;
-+ struct dc_context *ctx = NULL;
-+
-+ ctx = engine->base.base.base.ctx;
-+
-+ {
-+ const uint32_t addr = engine->addr.DC_I2C_DDCX_SETUP;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_DDC1_SETUP,
-+ DC_I2C_DDC1_DATA_DRIVE_EN);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_DDC1_SETUP,
-+ DC_I2C_DDC1_CLK_DRIVE_EN);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_DDC1_SETUP,
-+ DC_I2C_DDC1_DATA_DRIVE_SEL);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_DDC1_SETUP,
-+ DC_I2C_DDC1_INTRA_TRANSACTION_DELAY);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_DDC1_SETUP,
-+ DC_I2C_DDC1_INTRA_BYTE_DELAY);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+
-+ {
-+ const uint32_t addr = mmDC_I2C_CONTROL;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_CONTROL,
-+ DC_I2C_SOFT_RESET);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_CONTROL,
-+ DC_I2C_SW_STATUS_RESET);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_CONTROL,
-+ DC_I2C_SEND_RESET);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_CONTROL,
-+ DC_I2C_GO);
-+
-+ set_reg_field_value(
-+ value,
-+ engine->transaction_count - 1,
-+ DC_I2C_CONTROL,
-+ DC_I2C_TRANSACTION_COUNT);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+
-+ /* start I2C transfer */
-+ {
-+ const uint32_t addr = mmDC_I2C_CONTROL;
-+
-+ value = dal_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_CONTROL,
-+ DC_I2C_GO);
-+
-+ dal_write_reg(ctx, addr, value);
-+ }
-+
-+ /* all transactions were executed and HW buffer became empty
-+ * (even though it actually happens when status becomes DONE) */
-+ engine->transaction_count = 0;
-+ engine->buffer_used_bytes = 0;
-+}
-+
-+static void submit_channel_request(
-+ struct i2c_engine *engine,
-+ struct i2c_request_transaction_data *request)
-+{
-+ request->status = I2C_CHANNEL_OPERATION_SUCCEEDED;
-+
-+ if (!process_transaction(FROM_I2C_ENGINE(engine), request))
-+ return;
-+
-+ if (is_hw_busy(&engine->base)) {
-+ request->status = I2C_CHANNEL_OPERATION_ENGINE_BUSY;
-+ return;
-+ }
-+
-+ execute_transaction(FROM_I2C_ENGINE(engine));
-+}
-+
-+static void process_channel_reply(
-+ struct i2c_engine *engine,
-+ struct i2c_reply_transaction_data *reply)
-+{
-+ uint8_t length = reply->length;
-+ uint8_t *buffer = reply->data;
-+
-+ struct i2c_hw_engine_dce110 *i2c_hw_engine_dce110 =
-+ FROM_I2C_ENGINE(engine);
-+
-+ uint32_t value = 0;
-+
-+ /*set index*/
-+ set_reg_field_value(
-+ value,
-+ i2c_hw_engine_dce110->buffer_used_write,
-+ DC_I2C_DATA,
-+ DC_I2C_INDEX);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_DATA,
-+ DC_I2C_DATA_RW);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_DATA,
-+ DC_I2C_INDEX_WRITE);
-+
-+ dal_write_reg(engine->base.ctx, mmDC_I2C_DATA, value);
-+
-+ while (length) {
-+ /* after reading the status,
-+ * if the I2C operation executed successfully
-+ * (i.e. DC_I2C_STATUS_DONE = 1) then the I2C controller
-+ * should read data bytes from I2C circular data buffer */
-+
-+ value = dal_read_reg(engine->base.ctx, mmDC_I2C_DATA);
-+
-+ *buffer++ = get_reg_field_value(
-+ value,
-+ DC_I2C_DATA,
-+ DC_I2C_DATA);
-+
-+ --length;
-+ }
-+}
-+
-+static enum i2c_channel_operation_result get_channel_status(
-+ struct i2c_engine *engine,
-+ uint8_t *returned_bytes)
-+{
-+ uint32_t i2c_sw_status = 0;
-+ uint32_t value = dal_read_reg(engine->base.ctx, mmDC_I2C_SW_STATUS);
-+
-+ i2c_sw_status = get_reg_field_value(
-+ value,
-+ DC_I2C_SW_STATUS,
-+ DC_I2C_SW_STATUS);
-+
-+ if (i2c_sw_status == DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_SW)
-+ return I2C_CHANNEL_OPERATION_ENGINE_BUSY;
-+ else if (value & DC_I2C_SW_STATUS__DC_I2C_SW_STOPPED_ON_NACK_MASK)
-+ return I2C_CHANNEL_OPERATION_NO_RESPONSE;
-+ else if (value & DC_I2C_SW_STATUS__DC_I2C_SW_TIMEOUT_MASK)
-+ return I2C_CHANNEL_OPERATION_TIMEOUT;
-+ else if (value & DC_I2C_SW_STATUS__DC_I2C_SW_ABORTED_MASK)
-+ return I2C_CHANNEL_OPERATION_FAILED;
-+ else if (value & DC_I2C_SW_STATUS__DC_I2C_SW_DONE_MASK)
-+ return I2C_CHANNEL_OPERATION_SUCCEEDED;
-+
-+ /* in DAL2, I2C_RESULT_OK was returned */
-+ return I2C_CHANNEL_OPERATION_NOT_STARTED;
-+}
-+
-+static uint8_t get_hw_buffer_available_size(
-+ const struct i2c_hw_engine *engine)
-+{
-+ return I2C_HW_BUFFER_SIZE -
-+ FROM_I2C_HW_ENGINE(engine)->buffer_used_bytes;
-+}
-+
-+static uint32_t get_transaction_timeout(
-+ const struct i2c_hw_engine *engine,
-+ uint32_t length)
-+{
-+ uint32_t speed = engine->base.funcs->get_speed(&engine->base);
-+
-+ uint32_t period_timeout;
-+ uint32_t num_of_clock_stretches;
-+
-+ if (!speed)
-+ return 0;
-+
-+ period_timeout = (1000 * TRANSACTION_TIMEOUT_IN_I2C_CLOCKS) / speed;
-+
-+ num_of_clock_stretches = 1 + (length << 3) + 1;
-+ num_of_clock_stretches +=
-+ (FROM_I2C_HW_ENGINE(engine)->buffer_used_bytes << 3) +
-+ (FROM_I2C_HW_ENGINE(engine)->transaction_count << 1);
-+
-+ return period_timeout * num_of_clock_stretches;
-+}
-+
-+static void destroy(
-+ struct i2c_engine **i2c_engine)
-+{
-+ struct i2c_hw_engine_dce110 *engine_dce110 =
-+ FROM_I2C_ENGINE(*i2c_engine);
-+
-+ dal_i2c_hw_engine_destruct(&engine_dce110->base);
-+
-+ dc_service_free((*i2c_engine)->base.ctx, engine_dce110);
-+
-+ *i2c_engine = NULL;
-+}
-+/*
-+ * @brief
-+ * DC_I2C_DDC1_SETUP MM register offsets
-+ *
-+ * @note
-+ * The indices of this offset array are DDC engine IDs
-+ */
-+static const int32_t ddc_setup_offset[] = {
-+
-+ mmDC_I2C_DDC1_SETUP - mmDC_I2C_DDC1_SETUP, /* DDC Engine 1 */
-+ mmDC_I2C_DDC2_SETUP - mmDC_I2C_DDC1_SETUP, /* DDC Engine 2 */
-+ mmDC_I2C_DDC3_SETUP - mmDC_I2C_DDC1_SETUP, /* DDC Engine 3 */
-+ mmDC_I2C_DDC4_SETUP - mmDC_I2C_DDC1_SETUP, /* DDC Engine 4 */
-+ mmDC_I2C_DDC5_SETUP - mmDC_I2C_DDC1_SETUP, /* DDC Engine 5 */
-+ mmDC_I2C_DDC6_SETUP - mmDC_I2C_DDC1_SETUP, /* DDC Engine 6 */
-+ mmDC_I2C_DDCVGA_SETUP - mmDC_I2C_DDC1_SETUP /* DDC Engine 7 */
-+};
-+
-+/*
-+ * @brief
-+ * DC_I2C_DDC1_SPEED MM register offsets
-+ *
-+ * @note
-+ * The indices of this offset array are DDC engine IDs
-+ */
-+static const int32_t ddc_speed_offset[] = {
-+ mmDC_I2C_DDC1_SPEED - mmDC_I2C_DDC1_SPEED, /* DDC Engine 1 */
-+ mmDC_I2C_DDC2_SPEED - mmDC_I2C_DDC1_SPEED, /* DDC Engine 2 */
-+ mmDC_I2C_DDC3_SPEED - mmDC_I2C_DDC1_SPEED, /* DDC Engine 3 */
-+ mmDC_I2C_DDC4_SPEED - mmDC_I2C_DDC1_SPEED, /* DDC Engine 4 */
-+ mmDC_I2C_DDC5_SPEED - mmDC_I2C_DDC1_SPEED, /* DDC Engine 5 */
-+ mmDC_I2C_DDC6_SPEED - mmDC_I2C_DDC1_SPEED, /* DDC Engine 6 */
-+ mmDC_I2C_DDCVGA_SPEED - mmDC_I2C_DDC1_SPEED /* DDC Engine 7 */
-+};
-+
-+static const struct i2c_engine_funcs i2c_engine_funcs = {
-+ .destroy = destroy,
-+ .get_speed = get_speed,
-+ .set_speed = set_speed,
-+ .setup_engine = setup_engine,
-+ .submit_channel_request = submit_channel_request,
-+ .process_channel_reply = process_channel_reply,
-+ .get_channel_status = get_channel_status,
-+ .acquire_engine = dal_i2c_hw_engine_acquire_engine,
-+};
-+
-+static const struct engine_funcs engine_funcs = {
-+ .release_engine = release_engine,
-+ .keep_power_up_count = keep_power_up_count,
-+ .get_engine_type = dal_i2c_hw_engine_get_engine_type,
-+ .acquire = dal_i2c_engine_acquire,
-+ .submit_request = dal_i2c_hw_engine_submit_request,
-+};
-+
-+static const struct i2c_hw_engine_funcs i2c_hw_engine_funcs = {
-+ .get_hw_buffer_available_size = get_hw_buffer_available_size,
-+ .get_transaction_timeout = get_transaction_timeout,
-+ .wait_on_operation_result = dal_i2c_hw_engine_wait_on_operation_result,
-+};
-+
-+static bool construct(
-+ struct i2c_hw_engine_dce110 *engine_dce110,
-+ const struct i2c_hw_engine_dce110_create_arg *arg)
-+{
-+ uint32_t xtal_ref_div = 0;
-+ uint32_t value = 0;
-+
-+ /*ddc_setup_offset of dce80 and dce110 have the same register name
-+ * but different offset. Do not need different array*/
-+ if (arg->engine_id >= sizeof(ddc_setup_offset) / sizeof(int32_t))
-+ return false;
-+ if (arg->engine_id >= sizeof(ddc_speed_offset) / sizeof(int32_t))
-+ return false;
-+ if (!arg->reference_frequency)
-+ return false;
-+
-+ if (!dal_i2c_hw_engine_construct(&engine_dce110->base, arg->ctx))
-+ return false;
-+
-+ engine_dce110->base.base.base.funcs = &engine_funcs;
-+ engine_dce110->base.base.funcs = &i2c_engine_funcs;
-+ engine_dce110->base.funcs = &i2c_hw_engine_funcs;
-+ engine_dce110->base.default_speed = arg->default_speed;
-+
-+ engine_dce110->engine_id = arg->engine_id;
-+
-+ engine_dce110->buffer_used_bytes = 0;
-+ engine_dce110->transaction_count = 0;
-+ engine_dce110->engine_keep_power_up_count = 1;
-+
-+ /*values which are not included by arg*/
-+ engine_dce110->addr.DC_I2C_DDCX_SETUP =
-+ mmDC_I2C_DDC1_SETUP + ddc_setup_offset[arg->engine_id];
-+ engine_dce110->addr.DC_I2C_DDCX_SPEED =
-+ mmDC_I2C_DDC1_SPEED + ddc_speed_offset[arg->engine_id];
-+
-+
-+ value = dal_read_reg(
-+ engine_dce110->base.base.base.ctx,
-+ mmMICROSECOND_TIME_BASE_DIV);
-+
-+ xtal_ref_div = get_reg_field_value(
-+ value,
-+ MICROSECOND_TIME_BASE_DIV,
-+ XTAL_REF_DIV);
-+
-+ if (xtal_ref_div == 0) {
-+ dal_logger_write(
-+ engine_dce110->base.base.base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_I2C_AUX,
-+ "Invalid base timer divider\n",
-+ __func__);
-+ xtal_ref_div = 2;
-+ }
-+
-+ /*Calculating Reference Clock by divding original frequency by
-+ * XTAL_REF_DIV.
-+ * At upper level, uint32_t reference_frequency =
-+ * dal_i2caux_get_reference_clock(as) >> 1
-+ * which already divided by 2. So we need x2 to get original
-+ * reference clock from ppll_info
-+ */
-+ engine_dce110->reference_frequency =
-+ (arg->reference_frequency * 2) / xtal_ref_div;
-+
-+
-+ return true;
-+}
-+
-+struct i2c_engine *dal_i2c_hw_engine_dce110_create(
-+ const struct i2c_hw_engine_dce110_create_arg *arg)
-+{
-+ struct i2c_hw_engine_dce110 *engine_dce10;
-+
-+ if (!arg) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ engine_dce10 = dc_service_alloc(arg->ctx, sizeof(struct i2c_hw_engine_dce110));
-+
-+ if (!engine_dce10) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ if (construct(engine_dce10, arg))
-+ return &engine_dce10->base.base;
-+
-+ ASSERT_CRITICAL(false);
-+
-+ dc_service_free(arg->ctx, engine_dce10);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.h b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.h
-new file mode 100644
-index 0000000..fc2ae36
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_hw_engine_dce110.h
-@@ -0,0 +1,58 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_I2C_HW_ENGINE_DCE110_H__
-+#define __DAL_I2C_HW_ENGINE_DCE110_H__
-+
-+struct i2c_hw_engine_dce110 {
-+ struct i2c_hw_engine base;
-+ struct {
-+ uint32_t DC_I2C_DDCX_SETUP;
-+ uint32_t DC_I2C_DDCX_SPEED;
-+ } addr;
-+ uint32_t engine_id;
-+ /* expressed in kilohertz */
-+ uint32_t reference_frequency;
-+ /* number of bytes currently used in HW buffer */
-+ uint32_t buffer_used_bytes;
-+ /* number of bytes used for write transaction in HW buffer
-+ * - this will be used as the index to read from*/
-+ uint32_t buffer_used_write;
-+ /* number of pending transactions (before GO) */
-+ uint32_t transaction_count;
-+ uint32_t engine_keep_power_up_count;
-+};
-+
-+struct i2c_hw_engine_dce110_create_arg {
-+ uint32_t engine_id;
-+ uint32_t reference_frequency;
-+ uint32_t default_speed;
-+ struct dc_context *ctx;
-+};
-+
-+struct i2c_engine *dal_i2c_hw_engine_dce110_create(
-+ const struct i2c_hw_engine_dce110_create_arg *arg);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_sw_engine_dce110.c b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_sw_engine_dce110.c
-new file mode 100644
-index 0000000..c415a4e
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_sw_engine_dce110.c
-@@ -0,0 +1,172 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/i2caux_interface.h"
-+#include "../engine.h"
-+#include "../i2c_engine.h"
-+#include "../i2c_sw_engine.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "i2c_sw_engine_dce110.h"
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+/*
-+ * @brief
-+ * Cast 'struct i2c_sw_engine *'
-+ * to 'struct i2c_sw_engine_dce110 *'
-+ */
-+#define FROM_I2C_SW_ENGINE(ptr) \
-+ container_of((ptr), struct i2c_sw_engine_dce110, base)
-+/*
-+ * @brief
-+ * Cast 'struct i2c_engine *'
-+ * to 'struct i2c_sw_engine_dce80 *'
-+ */
-+#define FROM_I2C_ENGINE(ptr) \
-+ FROM_I2C_SW_ENGINE(container_of((ptr), struct i2c_sw_engine, base))
-+
-+/*
-+ * @brief
-+ * Cast 'struct engine *'
-+ * to 'struct i2c_sw_engine_dce80 *'
-+ */
-+#define FROM_ENGINE(ptr) \
-+ FROM_I2C_ENGINE(container_of((ptr), struct i2c_engine, base))
-+
-+static void release_engine(
-+ struct engine *engine)
-+{
-+}
-+
-+static void destruct(
-+ struct i2c_sw_engine_dce110 *engine)
-+{
-+ dal_i2c_sw_engine_destruct(&engine->base);
-+}
-+
-+static void destroy(
-+ struct i2c_engine **engine)
-+{
-+ struct i2c_sw_engine_dce110 *sw_engine = FROM_I2C_ENGINE(*engine);
-+
-+ destruct(sw_engine);
-+
-+ dc_service_free((*engine)->base.ctx, sw_engine);
-+
-+ *engine = NULL;
-+}
-+
-+static bool acquire_engine(
-+ struct i2c_engine *engine,
-+ struct ddc *ddc_handle)
-+{
-+ return dal_i2caux_i2c_sw_engine_acquire_engine(engine, ddc_handle);
-+}
-+
-+static const struct i2c_engine_funcs i2c_engine_funcs = {
-+ .acquire_engine = acquire_engine,
-+ .destroy = destroy,
-+ .get_speed = dal_i2c_sw_engine_get_speed,
-+ .set_speed = dal_i2c_sw_engine_set_speed,
-+ .setup_engine = dal_i2c_engine_setup_i2c_engine,
-+ .submit_channel_request = dal_i2c_sw_engine_submit_channel_request,
-+ .process_channel_reply = dal_i2c_engine_process_channel_reply,
-+ .get_channel_status = dal_i2c_sw_engine_get_channel_status,
-+};
-+
-+static const struct engine_funcs engine_funcs = {
-+ .release_engine = release_engine,
-+ .get_engine_type = dal_i2c_sw_engine_get_engine_type,
-+ .acquire = dal_i2c_engine_acquire,
-+ .submit_request = dal_i2c_sw_engine_submit_request,
-+ .keep_power_up_count = dal_i2caux_keep_power_up_count,
-+};
-+
-+static bool construct(
-+ struct i2c_sw_engine_dce110 *engine_dce110,
-+ const struct i2c_sw_engine_dce110_create_arg *arg_dce110)
-+{
-+ struct i2c_sw_engine_create_arg arg_base;
-+
-+ arg_base.ctx = arg_dce110->ctx;
-+ arg_base.default_speed = arg_dce110->default_speed;
-+
-+ if (!dal_i2c_sw_engine_construct(
-+ &engine_dce110->base, &arg_base)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ /*struct engine struct engine_funcs*/
-+ engine_dce110->base.base.base.funcs = &engine_funcs;
-+ /*struct i2c_engine struct i2c_engine_funcs*/
-+ engine_dce110->base.base.funcs = &i2c_engine_funcs;
-+ engine_dce110->base.default_speed = arg_dce110->default_speed;
-+ engine_dce110->engine_id = arg_dce110->engine_id;
-+
-+ return true;
-+}
-+
-+struct i2c_engine *dal_i2c_sw_engine_dce110_create(
-+ const struct i2c_sw_engine_dce110_create_arg *arg)
-+{
-+ struct i2c_sw_engine_dce110 *engine_dce110;
-+
-+ if (!arg) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ engine_dce110 = dc_service_alloc(arg->ctx, sizeof(struct i2c_sw_engine_dce110));
-+
-+ if (!engine_dce110) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ if (construct(engine_dce110, arg))
-+ return &engine_dce110->base.base;
-+
-+ ASSERT_CRITICAL(false);
-+
-+ dc_service_free(arg->ctx, engine_dce110);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_sw_engine_dce110.h b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_sw_engine_dce110.h
-new file mode 100644
-index 0000000..c48c61f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2c_sw_engine_dce110.h
-@@ -0,0 +1,43 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_I2C_SW_ENGINE_DCE110_H__
-+#define __DAL_I2C_SW_ENGINE_DCE110_H__
-+
-+struct i2c_sw_engine_dce110 {
-+ struct i2c_sw_engine base;
-+ uint32_t engine_id;
-+};
-+
-+struct i2c_sw_engine_dce110_create_arg {
-+ uint32_t engine_id;
-+ uint32_t default_speed;
-+ struct dc_context *ctx;
-+};
-+
-+struct i2c_engine *dal_i2c_sw_engine_dce110_create(
-+ const struct i2c_sw_engine_dce110_create_arg *arg);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.c b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.c
-new file mode 100644
-index 0000000..71d1a6c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.c
-@@ -0,0 +1,260 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/i2caux_interface.h"
-+#include "../i2caux.h"
-+#include "../engine.h"
-+#include "../i2c_engine.h"
-+#include "../i2c_sw_engine.h"
-+#include "../i2c_hw_engine.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+#include "i2caux_dce110.h"
-+#include "i2c_sw_engine_dce110.h"
-+#include "i2c_hw_engine_dce110.h"
-+#include "aux_engine_dce110.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+/*cast pointer to struct i2caux TO pointer to struct i2caux_dce110*/
-+#define FROM_I2C_AUX(ptr) \
-+ container_of((ptr), struct i2caux_dce110, base)
-+
-+static void destruct(
-+ struct i2caux_dce110 *i2caux_dce110)
-+{
-+ dal_i2caux_destruct(&i2caux_dce110->base);
-+}
-+
-+static void destroy(
-+ struct i2caux **i2c_engine)
-+{
-+ struct i2caux_dce110 *i2caux_dce110 = FROM_I2C_AUX(*i2c_engine);
-+
-+ destruct(i2caux_dce110);
-+
-+ dc_service_free((*i2c_engine)->ctx, i2caux_dce110);
-+
-+ *i2c_engine = NULL;
-+}
-+
-+static struct i2c_engine *acquire_i2c_hw_engine(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc)
-+{
-+ struct i2caux_dce110 *i2caux_dce110 = FROM_I2C_AUX(i2caux);
-+
-+ struct i2c_engine *engine = NULL;
-+ /* generic hw engine is not used for EDID read
-+ * It may be needed for external i2c device, like thermal chip,
-+ * TODO will be implemented when needed.
-+ * check dce80 bool non_generic for generic hw engine;
-+ */
-+
-+ if (!ddc)
-+ return NULL;
-+
-+ if (dal_ddc_is_hw_supported(ddc)) {
-+ enum gpio_ddc_line line = dal_ddc_get_line(ddc);
-+
-+ if (line < GPIO_DDC_LINE_COUNT)
-+ engine = i2caux->i2c_hw_engines[line];
-+ }
-+
-+ if (!engine)
-+ return NULL;
-+
-+ if (!i2caux_dce110->i2c_hw_buffer_in_use &&
-+ engine->base.funcs->acquire(&engine->base, ddc)) {
-+ i2caux_dce110->i2c_hw_buffer_in_use = true;
-+ return engine;
-+ }
-+
-+ return NULL;
-+}
-+
-+static void release_engine(
-+ struct i2caux *i2caux,
-+ struct engine *engine)
-+{
-+ struct i2caux_dce110 *i2caux_dce110 = FROM_I2C_AUX(i2caux);
-+
-+ if (engine->funcs->get_engine_type(engine) ==
-+ I2CAUX_ENGINE_TYPE_I2C_DDC_HW)
-+ i2caux_dce110->i2c_hw_buffer_in_use = false;
-+
-+ dal_i2caux_release_engine(i2caux, engine);
-+}
-+
-+static const enum gpio_ddc_line hw_ddc_lines[] = {
-+ GPIO_DDC_LINE_DDC1,
-+ GPIO_DDC_LINE_DDC2,
-+ GPIO_DDC_LINE_DDC3,
-+};
-+
-+static const enum gpio_ddc_line hw_aux_lines[] = {
-+ GPIO_DDC_LINE_DDC1,
-+ GPIO_DDC_LINE_DDC2,
-+ GPIO_DDC_LINE_DDC3,
-+};
-+
-+/* function table */
-+static const struct i2caux_funcs i2caux_funcs = {
-+ .destroy = destroy,
-+ .acquire_i2c_hw_engine = acquire_i2c_hw_engine,
-+ .release_engine = release_engine,
-+ .acquire_i2c_sw_engine = dal_i2caux_acquire_i2c_sw_engine,
-+ .acquire_aux_engine = dal_i2caux_acquire_aux_engine,
-+};
-+
-+static bool construct(
-+ struct i2caux_dce110 *i2caux_dce110,
-+ struct adapter_service *as,
-+ struct dc_context *ctx)
-+{
-+ uint32_t i = 0;
-+ uint32_t reference_frequency = 0;
-+ bool use_i2c_sw_engine = false;
-+ struct i2caux *base = NULL;
-+ /*TODO: For CZ bring up, if dal_i2caux_get_reference_clock
-+ * does not return 48KHz, we need hard coded for 48Khz.
-+ * Some BIOS setting incorrect cause this
-+ * For production, we always get value from BIOS*/
-+ reference_frequency =
-+ dal_i2caux_get_reference_clock(as) >> 1;
-+
-+ use_i2c_sw_engine = dal_adapter_service_is_feature_supported(
-+ FEATURE_RESTORE_USAGE_I2C_SW_ENGINE);
-+
-+ base = &i2caux_dce110->base;
-+
-+ if (!dal_i2caux_construct(base, as, ctx)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ i2caux_dce110->base.funcs = &i2caux_funcs;
-+ i2caux_dce110->i2c_hw_buffer_in_use = false;
-+ /* Create I2C engines (DDC lines per connector)
-+ * different I2C/AUX usage cases, DDC, Generic GPIO, AUX.
-+ */
-+ do {
-+ enum gpio_ddc_line line_id = hw_ddc_lines[i];
-+
-+ struct i2c_hw_engine_dce110_create_arg hw_arg_dce110;
-+
-+ if (use_i2c_sw_engine) {
-+ struct i2c_sw_engine_dce110_create_arg sw_arg;
-+
-+ sw_arg.engine_id = i;
-+ sw_arg.default_speed = base->default_i2c_sw_speed;
-+ sw_arg.ctx = ctx;
-+ base->i2c_sw_engines[line_id] =
-+ dal_i2c_sw_engine_dce110_create(&sw_arg);
-+ }
-+
-+ hw_arg_dce110.engine_id = i;
-+ hw_arg_dce110.reference_frequency = reference_frequency;
-+ hw_arg_dce110.default_speed = base->default_i2c_hw_speed;
-+ hw_arg_dce110.ctx = ctx;
-+
-+ base->i2c_hw_engines[line_id] =
-+ dal_i2c_hw_engine_dce110_create(&hw_arg_dce110);
-+
-+ ++i;
-+ } while (i < ARRAY_SIZE(hw_ddc_lines));
-+
-+ /* Create AUX engines for all lines which has assisted HW AUX
-+ * 'i' (loop counter) used as DDC/AUX engine_id */
-+
-+ i = 0;
-+
-+ do {
-+ enum gpio_ddc_line line_id = hw_aux_lines[i];
-+
-+ struct aux_engine_dce110_init_data aux_init_data;
-+
-+ aux_init_data.engine_id = i;
-+ aux_init_data.timeout_period = base->aux_timeout_period;
-+ aux_init_data.ctx = ctx;
-+
-+ base->aux_engines[line_id] =
-+ dal_aux_engine_dce110_create(&aux_init_data);
-+
-+ ++i;
-+ } while (i < ARRAY_SIZE(hw_aux_lines));
-+
-+ /*TODO Generic I2C SW and HW*/
-+
-+ return true;
-+}
-+
-+/*
-+ * dal_i2caux_dce110_create
-+ *
-+ * @brief
-+ * public interface to allocate memory for DCE11 I2CAUX
-+ *
-+ * @param
-+ * struct adapter_service *as - [in]
-+ * struct dc_context *ctx - [in]
-+ *
-+ * @return
-+ * pointer to the base struct of DCE11 I2CAUX
-+ */
-+struct i2caux *dal_i2caux_dce110_create(
-+ struct adapter_service *as,
-+ struct dc_context *ctx)
-+{
-+ struct i2caux_dce110 *i2caux_dce110 =
-+ dc_service_alloc(ctx, sizeof(struct i2caux_dce110));
-+
-+ if (!i2caux_dce110) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ if (construct(i2caux_dce110, as, ctx))
-+ return &i2caux_dce110->base;
-+
-+ ASSERT_CRITICAL(false);
-+
-+ dc_service_free(ctx, i2caux_dce110);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.h b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.h
-new file mode 100644
-index 0000000..1a7ba1b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce110/i2caux_dce110.h
-@@ -0,0 +1,39 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_I2C_AUX_DCE110_H__
-+#define __DAL_I2C_AUX_DCE110_H__
-+
-+struct i2caux_dce110 {
-+ struct i2caux base;
-+ /* indicate the I2C HW circular buffer is in use */
-+ bool i2c_hw_buffer_in_use;
-+};
-+
-+struct i2caux *dal_i2caux_dce110_create(
-+ struct adapter_service *as,
-+ struct dc_context *ctx);
-+
-+#endif /* __DAL_I2C_AUX_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/engine.h b/drivers/gpu/drm/amd/dal/dc/i2caux/engine.h
-new file mode 100644
-index 0000000..d3635f8
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/engine.h
-@@ -0,0 +1,129 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_ENGINE_H__
-+#define __DAL_ENGINE_H__
-+
-+enum i2caux_transaction_operation {
-+ I2CAUX_TRANSACTION_READ,
-+ I2CAUX_TRANSACTION_WRITE
-+};
-+
-+enum i2caux_transaction_address_space {
-+ I2CAUX_TRANSACTION_ADDRESS_SPACE_I2C = 1,
-+ I2CAUX_TRANSACTION_ADDRESS_SPACE_DPCD
-+};
-+
-+struct i2caux_transaction_payload {
-+ enum i2caux_transaction_address_space address_space;
-+ uint32_t address;
-+ uint8_t length;
-+ uint8_t *data;
-+};
-+
-+enum i2caux_transaction_status {
-+ I2CAUX_TRANSACTION_STATUS_UNKNOWN = (-1L),
-+ I2CAUX_TRANSACTION_STATUS_SUCCEEDED,
-+ I2CAUX_TRANSACTION_STATUS_FAILED_CHANNEL_BUSY,
-+ I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT,
-+ I2CAUX_TRANSACTION_STATUS_FAILED_PROTOCOL_ERROR,
-+ I2CAUX_TRANSACTION_STATUS_FAILED_NACK,
-+ I2CAUX_TRANSACTION_STATUS_FAILED_INCOMPLETE,
-+ I2CAUX_TRANSACTION_STATUS_FAILED_OPERATION,
-+ I2CAUX_TRANSACTION_STATUS_FAILED_INVALID_OPERATION,
-+ I2CAUX_TRANSACTION_STATUS_FAILED_BUFFER_OVERFLOW
-+};
-+
-+struct i2caux_transaction_request {
-+ enum i2caux_transaction_operation operation;
-+ struct i2caux_transaction_payload payload;
-+ enum i2caux_transaction_status status;
-+};
-+
-+enum i2caux_engine_type {
-+ I2CAUX_ENGINE_TYPE_UNKNOWN = (-1L),
-+ I2CAUX_ENGINE_TYPE_AUX,
-+ I2CAUX_ENGINE_TYPE_I2C_DDC_HW,
-+ I2CAUX_ENGINE_TYPE_I2C_GENERIC_HW,
-+ I2CAUX_ENGINE_TYPE_I2C_SW
-+};
-+
-+enum i2c_default_speed {
-+ I2CAUX_DEFAULT_I2C_HW_SPEED = 50,
-+ I2CAUX_DEFAULT_I2C_SW_SPEED = 50
-+};
-+
-+enum i2caux_transaction_action {
-+ I2CAUX_TRANSACTION_ACTION_I2C_WRITE = 0x00,
-+ I2CAUX_TRANSACTION_ACTION_I2C_READ = 0x10,
-+ I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST = 0x20,
-+
-+ I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT = 0x40,
-+ I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT = 0x50,
-+ I2CAUX_TRANSACTION_ACTION_I2C_STATUS_REQUEST_MOT = 0x60,
-+
-+ I2CAUX_TRANSACTION_ACTION_DP_WRITE = 0x80,
-+ I2CAUX_TRANSACTION_ACTION_DP_READ = 0x90
-+};
-+
-+struct engine;
-+
-+struct engine_funcs {
-+ enum i2caux_engine_type (*get_engine_type)(
-+ const struct engine *engine);
-+ bool (*acquire)(
-+ struct engine *engine,
-+ struct ddc *ddc);
-+ bool (*submit_request)(
-+ struct engine *engine,
-+ struct i2caux_transaction_request *request,
-+ bool middle_of_transaction);
-+ /* [anaumov] Actually, following method is meaningful
-+ * only in I2C HW engines */
-+ void (*keep_power_up_count)(
-+ struct engine *engine,
-+ bool keep_power_up);
-+ void (*release_engine)(
-+ struct engine *engine);
-+};
-+
-+struct engine {
-+ const struct engine_funcs *funcs;
-+ struct ddc *ddc;
-+ struct dc_context *ctx;
-+};
-+
-+bool dal_i2caux_construct_engine(
-+ struct engine *engine,
-+ struct dc_context *ctx);
-+
-+void dal_i2caux_destruct_engine(
-+ struct engine *engine);
-+
-+void dal_i2caux_keep_power_up_count(
-+ struct engine *engine,
-+ bool keep_power_up);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/engine_base.c b/drivers/gpu/drm/amd/dal/dc/i2caux/engine_base.c
-new file mode 100644
-index 0000000..2f87a65
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/engine_base.c
-@@ -0,0 +1,68 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/i2caux_interface.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "engine.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+void dal_i2caux_keep_power_up_count(
-+ struct engine *engine,
-+ bool keep_power_up)
-+{
-+
-+}
-+
-+bool dal_i2caux_construct_engine(
-+ struct engine *engine,
-+ struct dc_context *ctx)
-+{
-+ engine->ddc = NULL;
-+ engine->ctx = ctx;
-+ return true;
-+}
-+
-+void dal_i2caux_destruct_engine(
-+ struct engine *engine)
-+{
-+ /* nothing to do */
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_engine.c b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_engine.c
-new file mode 100644
-index 0000000..78c7d61
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_engine.c
-@@ -0,0 +1,122 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/i2caux_interface.h"
-+#include "engine.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "i2c_engine.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+#define FROM_ENGINE(ptr) \
-+ container_of((ptr), struct i2c_engine, base)
-+
-+bool dal_i2c_engine_acquire(
-+ struct engine *engine,
-+ struct ddc *ddc_handle)
-+{
-+ struct i2c_engine *i2c_engine = FROM_ENGINE(engine);
-+
-+ uint32_t counter = 0;
-+ bool result;
-+
-+ do {
-+ result = i2c_engine->funcs->acquire_engine(
-+ i2c_engine, ddc_handle);
-+
-+ if (result)
-+ break;
-+
-+ /* i2c_engine is busy by VBios, lets wait and retry */
-+
-+ dc_service_delay_in_microseconds(engine->ctx, 10);
-+
-+ ++counter;
-+ } while (counter < 2);
-+
-+ if (result) {
-+ if (!i2c_engine->funcs->setup_engine(i2c_engine)) {
-+ engine->funcs->release_engine(engine);
-+ result = false;
-+ }
-+ }
-+
-+ return result;
-+}
-+
-+bool dal_i2c_engine_setup_i2c_engine(
-+ struct i2c_engine *engine)
-+{
-+ /* Derivative classes do not have to override this */
-+
-+ return true;
-+}
-+
-+void dal_i2c_engine_submit_channel_request(
-+ struct i2c_engine *engine,
-+ struct i2c_request_transaction_data *request)
-+{
-+
-+}
-+
-+void dal_i2c_engine_process_channel_reply(
-+ struct i2c_engine *engine,
-+ struct i2c_reply_transaction_data *reply)
-+{
-+
-+}
-+
-+bool dal_i2c_engine_construct(
-+ struct i2c_engine *engine,
-+ struct dc_context *ctx)
-+{
-+ if (!dal_i2caux_construct_engine(&engine->base, ctx))
-+ return false;
-+
-+ engine->timeout_delay = 0;
-+ return true;
-+}
-+
-+void dal_i2c_engine_destruct(
-+ struct i2c_engine *engine)
-+{
-+ dal_i2caux_destruct_engine(&engine->base);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_engine.h b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_engine.h
-new file mode 100644
-index 0000000..20299fd
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_engine.h
-@@ -0,0 +1,113 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_I2C_ENGINE_H__
-+#define __DAL_I2C_ENGINE_H__
-+
-+enum i2c_channel_operation_result {
-+ I2C_CHANNEL_OPERATION_SUCCEEDED,
-+ I2C_CHANNEL_OPERATION_FAILED,
-+ I2C_CHANNEL_OPERATION_NOT_GRANTED,
-+ I2C_CHANNEL_OPERATION_IS_BUSY,
-+ I2C_CHANNEL_OPERATION_NO_HANDLE_PROVIDED,
-+ I2C_CHANNEL_OPERATION_CHANNEL_IN_USE,
-+ I2C_CHANNEL_OPERATION_CHANNEL_CLIENT_MAX_ALLOWED,
-+ I2C_CHANNEL_OPERATION_ENGINE_BUSY,
-+ I2C_CHANNEL_OPERATION_TIMEOUT,
-+ I2C_CHANNEL_OPERATION_NO_RESPONSE,
-+ I2C_CHANNEL_OPERATION_HW_REQUEST_I2C_BUS,
-+ I2C_CHANNEL_OPERATION_WRONG_PARAMETER,
-+ I2C_CHANNEL_OPERATION_OUT_NB_OF_RETRIES,
-+ I2C_CHANNEL_OPERATION_NOT_STARTED
-+};
-+
-+struct i2c_request_transaction_data {
-+ enum i2caux_transaction_action action;
-+ enum i2c_channel_operation_result status;
-+ uint8_t address;
-+ uint8_t length;
-+ uint8_t *data;
-+};
-+
-+struct i2c_reply_transaction_data {
-+ uint8_t length;
-+ uint8_t *data;
-+};
-+
-+struct i2c_engine;
-+
-+struct i2c_engine_funcs {
-+ void (*destroy)(
-+ struct i2c_engine **ptr);
-+ uint32_t (*get_speed)(
-+ const struct i2c_engine *engine);
-+ void (*set_speed)(
-+ struct i2c_engine *engine,
-+ uint32_t speed);
-+ bool (*acquire_engine)(
-+ struct i2c_engine *engine,
-+ struct ddc *ddc);
-+ bool (*setup_engine)(
-+ struct i2c_engine *engine);
-+ void (*submit_channel_request)(
-+ struct i2c_engine *engine,
-+ struct i2c_request_transaction_data *request);
-+ void (*process_channel_reply)(
-+ struct i2c_engine *engine,
-+ struct i2c_reply_transaction_data *reply);
-+ enum i2c_channel_operation_result (*get_channel_status)(
-+ struct i2c_engine *engine,
-+ uint8_t *returned_bytes);
-+};
-+
-+struct i2c_engine {
-+ struct engine base;
-+ const struct i2c_engine_funcs *funcs;
-+ uint32_t timeout_delay;
-+};
-+
-+bool dal_i2c_engine_construct(
-+ struct i2c_engine *engine,
-+ struct dc_context *ctx);
-+
-+void dal_i2c_engine_destruct(
-+ struct i2c_engine *engine);
-+
-+bool dal_i2c_engine_setup_i2c_engine(
-+ struct i2c_engine *engine);
-+
-+void dal_i2c_engine_submit_channel_request(
-+ struct i2c_engine *engine,
-+ struct i2c_request_transaction_data *request);
-+
-+void dal_i2c_engine_process_channel_reply(
-+ struct i2c_engine *engine,
-+ struct i2c_reply_transaction_data *reply);
-+
-+bool dal_i2c_engine_acquire(
-+ struct engine *ptr,
-+ struct ddc *ddc_handle);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_generic_hw_engine.c b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_generic_hw_engine.c
-new file mode 100644
-index 0000000..d91e259
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_generic_hw_engine.c
-@@ -0,0 +1,287 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/i2caux_interface.h"
-+#include "engine.h"
-+#include "i2c_engine.h"
-+#include "i2c_hw_engine.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "i2c_generic_hw_engine.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+/*
-+ * @brief
-+ * Cast 'struct i2c_hw_engine *'
-+ * to 'struct i2c_generic_hw_engine *'
-+ */
-+#define FROM_I2C_HW_ENGINE(ptr) \
-+ container_of((ptr), struct i2c_generic_hw_engine, base)
-+
-+/*
-+ * @brief
-+ * Cast 'struct i2c_engine *'
-+ * to 'struct i2c_generic_hw_engine *'
-+ */
-+#define FROM_I2C_ENGINE(ptr) \
-+ FROM_I2C_HW_ENGINE(container_of((ptr), struct i2c_hw_engine, base))
-+
-+/*
-+ * @brief
-+ * Cast 'struct engine *'
-+ * to 'struct i2c_generic_hw_engine *'
-+ */
-+#define FROM_ENGINE(ptr) \
-+ FROM_I2C_ENGINE(container_of((ptr), struct i2c_engine, base))
-+
-+enum i2caux_engine_type dal_i2c_generic_hw_engine_get_engine_type(
-+ const struct engine *engine)
-+{
-+ return I2CAUX_ENGINE_TYPE_I2C_GENERIC_HW;
-+}
-+
-+/*
-+ * @brief
-+ * Single transaction handling.
-+ * Since transaction may be bigger than HW buffer size,
-+ * it divides transaction to sub-transactions
-+ * and uses batch transaction feature of the engine.
-+ */
-+bool dal_i2c_generic_hw_engine_submit_request(
-+ struct engine *engine,
-+ struct i2caux_transaction_request *i2caux_request,
-+ bool middle_of_transaction)
-+{
-+ struct i2c_generic_hw_engine *hw_engine = FROM_ENGINE(engine);
-+
-+ struct i2c_hw_engine *base = &hw_engine->base;
-+
-+ uint8_t max_payload_size =
-+ base->funcs->get_hw_buffer_available_size(base);
-+
-+ bool initial_stop_bit = !middle_of_transaction;
-+
-+ struct i2c_generic_transaction_attributes attributes;
-+
-+ enum i2c_channel_operation_result operation_result =
-+ I2C_CHANNEL_OPERATION_FAILED;
-+
-+ bool result = false;
-+
-+ /* setup transaction initial properties */
-+
-+ uint8_t address = i2caux_request->payload.address;
-+ uint8_t *current_payload = i2caux_request->payload.data;
-+ uint8_t remaining_payload_size = i2caux_request->payload.length;
-+
-+ bool first_iteration = true;
-+
-+ if (i2caux_request->operation == I2CAUX_TRANSACTION_READ)
-+ attributes.action = I2CAUX_TRANSACTION_ACTION_I2C_READ;
-+ else if (i2caux_request->operation == I2CAUX_TRANSACTION_WRITE)
-+ attributes.action = I2CAUX_TRANSACTION_ACTION_I2C_WRITE;
-+ else {
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_INVALID_OPERATION;
-+ return false;
-+ }
-+
-+ /* Do batch transaction.
-+ * Divide read/write data into payloads which fit HW buffer size.
-+ * 1. Single transaction:
-+ * start_bit = 1, stop_bit depends on session state, ack_on_read = 0;
-+ * 2. Start of batch transaction:
-+ * start_bit = 1, stop_bit = 0, ack_on_read = 1;
-+ * 3. Middle of batch transaction:
-+ * start_bit = 0, stop_bit = 0, ack_on_read = 1;
-+ * 4. End of batch transaction:
-+ * start_bit = 0, stop_bit depends on session state, ack_on_read = 0.
-+ * Session stop bit is set if 'middle_of_transaction' = 0. */
-+
-+ while (remaining_payload_size) {
-+ uint8_t current_transaction_size;
-+ uint8_t current_payload_size;
-+
-+ bool last_iteration;
-+ bool stop_bit;
-+
-+ /* Calculate current transaction size and payload size.
-+ * Transaction size = total number of bytes in transaction,
-+ * including slave's address;
-+ * Payload size = number of data bytes in transaction. */
-+
-+ if (first_iteration) {
-+ /* In the first sub-transaction we send slave's address
-+ * thus we need to reserve one byte for it */
-+ current_transaction_size =
-+ (remaining_payload_size > max_payload_size - 1) ?
-+ max_payload_size :
-+ remaining_payload_size + 1;
-+
-+ current_payload_size = current_transaction_size - 1;
-+ } else {
-+ /* Second and further sub-transactions will have
-+ * entire buffer reserved for data */
-+ current_transaction_size =
-+ (remaining_payload_size > max_payload_size) ?
-+ max_payload_size :
-+ remaining_payload_size;
-+
-+ current_payload_size = current_transaction_size;
-+ }
-+
-+ last_iteration =
-+ (remaining_payload_size == current_payload_size);
-+
-+ stop_bit = last_iteration ? initial_stop_bit : false;
-+
-+ /* write slave device address */
-+
-+ if (first_iteration)
-+ hw_engine->funcs->write_address(hw_engine, address);
-+
-+ /* write current portion of data, if requested */
-+
-+ if (i2caux_request->operation == I2CAUX_TRANSACTION_WRITE)
-+ hw_engine->funcs->write_data(
-+ hw_engine,
-+ current_payload,
-+ current_payload_size);
-+
-+ /* execute transaction */
-+
-+ attributes.start_bit = first_iteration;
-+ attributes.stop_bit = stop_bit;
-+ attributes.last_read = last_iteration;
-+ attributes.transaction_size = current_transaction_size;
-+
-+ hw_engine->funcs->execute_transaction(hw_engine, &attributes);
-+
-+ /* wait until transaction is processed; if it fails - quit */
-+
-+ operation_result = base->funcs->wait_on_operation_result(
-+ base,
-+ base->funcs->get_transaction_timeout(
-+ base, current_transaction_size),
-+ I2C_CHANNEL_OPERATION_ENGINE_BUSY);
-+
-+ if (operation_result != I2C_CHANNEL_OPERATION_SUCCEEDED)
-+ break;
-+
-+ /* read current portion of data, if requested */
-+
-+ /* the read offset should be 1 for first sub-transaction,
-+ * and 0 for any next one */
-+
-+ if (i2caux_request->operation == I2CAUX_TRANSACTION_READ)
-+ hw_engine->funcs->read_data(hw_engine, current_payload,
-+ current_payload_size, first_iteration ? 1 : 0);
-+
-+ /* update loop variables */
-+
-+ first_iteration = false;
-+ current_payload += current_payload_size;
-+ remaining_payload_size -= current_payload_size;
-+ }
-+
-+ /* update transaction status */
-+
-+ switch (operation_result) {
-+ case I2C_CHANNEL_OPERATION_SUCCEEDED:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_SUCCEEDED;
-+ result = true;
-+ break;
-+ case I2C_CHANNEL_OPERATION_NO_RESPONSE:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_NACK;
-+ break;
-+ case I2C_CHANNEL_OPERATION_TIMEOUT:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT;
-+ break;
-+ case I2C_CHANNEL_OPERATION_FAILED:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_INCOMPLETE;
-+ break;
-+ default:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_OPERATION;
-+ }
-+
-+ return result;
-+}
-+
-+/*
-+ * @brief
-+ * Returns number of microseconds to wait until timeout to be considered
-+ */
-+uint32_t dal_i2c_generic_hw_engine_get_transaction_timeout(
-+ const struct i2c_hw_engine *engine,
-+ uint32_t length)
-+{
-+ const struct i2c_engine *base = &engine->base;
-+
-+ uint32_t speed = base->funcs->get_speed(base);
-+
-+ if (!speed)
-+ return 0;
-+
-+ /* total timeout = period_timeout * (start + data bits count + stop) */
-+
-+ return ((1000 * TRANSACTION_TIMEOUT_IN_I2C_CLOCKS) / speed) *
-+ (1 + (length << 3) + 1);
-+}
-+
-+bool dal_i2c_generic_hw_engine_construct(
-+ struct i2c_generic_hw_engine *engine,
-+ struct dc_context *ctx)
-+{
-+ if (!dal_i2c_hw_engine_construct(&engine->base, ctx))
-+ return false;
-+ return true;
-+}
-+
-+void dal_i2c_generic_hw_engine_destruct(
-+ struct i2c_generic_hw_engine *engine)
-+{
-+ dal_i2c_hw_engine_destruct(&engine->base);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_generic_hw_engine.h b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_generic_hw_engine.h
-new file mode 100644
-index 0000000..52f2aa2
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_generic_hw_engine.h
-@@ -0,0 +1,77 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_I2C_GENERIC_HW_ENGINE_H__
-+#define __DAL_I2C_GENERIC_HW_ENGINE_H__
-+
-+struct i2c_generic_transaction_attributes {
-+ enum i2caux_transaction_action action;
-+ uint8_t transaction_size;
-+ bool start_bit;
-+ bool stop_bit;
-+ bool last_read;
-+};
-+
-+struct i2c_generic_hw_engine;
-+
-+struct i2c_generic_hw_engine_funcs {
-+ void (*write_address)(
-+ struct i2c_generic_hw_engine *engine,
-+ uint8_t address);
-+ void (*write_data)(
-+ struct i2c_generic_hw_engine *engine,
-+ const uint8_t *buffer,
-+ uint8_t length);
-+ void (*read_data)(
-+ struct i2c_generic_hw_engine *engine,
-+ uint8_t *buffer,
-+ uint8_t length,
-+ uint32_t offset);
-+ void (*execute_transaction)(
-+ struct i2c_generic_hw_engine *engine,
-+ struct i2c_generic_transaction_attributes *attributes);
-+};
-+
-+struct i2c_generic_hw_engine {
-+ struct i2c_hw_engine base;
-+ const struct i2c_generic_hw_engine_funcs *funcs;
-+};
-+
-+bool dal_i2c_generic_hw_engine_construct(
-+ struct i2c_generic_hw_engine *engine,
-+ struct dc_context *ctx);
-+
-+void dal_i2c_generic_hw_engine_destruct(
-+ struct i2c_generic_hw_engine *engine);
-+enum i2caux_engine_type dal_i2c_generic_hw_engine_get_engine_type(
-+ const struct engine *engine);
-+bool dal_i2c_generic_hw_engine_submit_request(
-+ struct engine *ptr,
-+ struct i2caux_transaction_request *i2caux_request,
-+ bool middle_of_transaction);
-+uint32_t dal_i2c_generic_hw_engine_get_transaction_timeout(
-+ const struct i2c_hw_engine *engine,
-+ uint32_t length);
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_hw_engine.c b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_hw_engine.c
-new file mode 100644
-index 0000000..77f2b84
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_hw_engine.c
-@@ -0,0 +1,247 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/i2caux_interface.h"
-+#include "engine.h"
-+#include "i2c_engine.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "i2c_hw_engine.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+/*
-+ * @brief
-+ * Cast 'struct i2c_engine *'
-+ * to 'struct i2c_hw_engine *'
-+ */
-+#define FROM_I2C_ENGINE(ptr) \
-+ container_of((ptr), struct i2c_hw_engine, base)
-+
-+/*
-+ * @brief
-+ * Cast 'struct engine *'
-+ * to 'struct i2c_hw_engine *'
-+ */
-+#define FROM_ENGINE(ptr) \
-+ FROM_I2C_ENGINE(container_of((ptr), struct i2c_engine, base))
-+
-+enum i2caux_engine_type dal_i2c_hw_engine_get_engine_type(
-+ const struct engine *engine)
-+{
-+ return I2CAUX_ENGINE_TYPE_I2C_DDC_HW;
-+}
-+
-+bool dal_i2c_hw_engine_submit_request(
-+ struct engine *engine,
-+ struct i2caux_transaction_request *i2caux_request,
-+ bool middle_of_transaction)
-+{
-+ struct i2c_hw_engine *hw_engine = FROM_ENGINE(engine);
-+
-+ struct i2c_request_transaction_data request;
-+
-+ uint32_t transaction_timeout;
-+
-+ enum i2c_channel_operation_result operation_result;
-+
-+ bool result = false;
-+
-+ /* We need following:
-+ * transaction length will not exceed
-+ * the number of free bytes in HW buffer (minus one for address)*/
-+
-+ if (i2caux_request->payload.length >=
-+ hw_engine->funcs->get_hw_buffer_available_size(hw_engine)) {
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_BUFFER_OVERFLOW;
-+ return false;
-+ }
-+
-+ if (i2caux_request->operation == I2CAUX_TRANSACTION_READ)
-+ request.action = middle_of_transaction ?
-+ I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT :
-+ I2CAUX_TRANSACTION_ACTION_I2C_READ;
-+ else if (i2caux_request->operation == I2CAUX_TRANSACTION_WRITE)
-+ request.action = middle_of_transaction ?
-+ I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT :
-+ I2CAUX_TRANSACTION_ACTION_I2C_WRITE;
-+ else {
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_INVALID_OPERATION;
-+ /* [anaumov] in DAL2, there was no "return false" */
-+ return false;
-+ }
-+
-+ request.address = (uint8_t)i2caux_request->payload.address;
-+ request.length = i2caux_request->payload.length;
-+ request.data = i2caux_request->payload.data;
-+
-+ /* obtain timeout value before submitting request */
-+
-+ transaction_timeout = hw_engine->funcs->get_transaction_timeout(
-+ hw_engine, i2caux_request->payload.length + 1);
-+
-+ hw_engine->base.funcs->submit_channel_request(
-+ &hw_engine->base, &request);
-+
-+ if ((request.status == I2C_CHANNEL_OPERATION_FAILED) ||
-+ (request.status == I2C_CHANNEL_OPERATION_ENGINE_BUSY)) {
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_CHANNEL_BUSY;
-+ return false;
-+ }
-+
-+ /* wait until transaction proceed */
-+
-+ operation_result = hw_engine->funcs->wait_on_operation_result(
-+ hw_engine,
-+ transaction_timeout,
-+ I2C_CHANNEL_OPERATION_ENGINE_BUSY);
-+
-+ /* update transaction status */
-+
-+ switch (operation_result) {
-+ case I2C_CHANNEL_OPERATION_SUCCEEDED:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_SUCCEEDED;
-+ result = true;
-+ break;
-+ case I2C_CHANNEL_OPERATION_NO_RESPONSE:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_NACK;
-+ break;
-+ case I2C_CHANNEL_OPERATION_TIMEOUT:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT;
-+ break;
-+ case I2C_CHANNEL_OPERATION_FAILED:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_INCOMPLETE;
-+ break;
-+ default:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_OPERATION;
-+ }
-+
-+ if (result && (i2caux_request->operation == I2CAUX_TRANSACTION_READ)) {
-+ struct i2c_reply_transaction_data reply;
-+
-+ reply.data = i2caux_request->payload.data;
-+ reply.length = i2caux_request->payload.length;
-+
-+ hw_engine->base.funcs->
-+ process_channel_reply(&hw_engine->base, &reply);
-+ }
-+
-+ return result;
-+}
-+
-+bool dal_i2c_hw_engine_acquire_engine(
-+ struct i2c_engine *engine,
-+ struct ddc *ddc)
-+{
-+ enum gpio_result result;
-+ uint32_t current_speed;
-+
-+ result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
-+ GPIO_DDC_CONFIG_TYPE_MODE_I2C);
-+
-+ if (result != GPIO_RESULT_OK)
-+ return false;
-+
-+ engine->base.ddc = ddc;
-+
-+ current_speed = engine->funcs->get_speed(engine);
-+
-+ if (current_speed)
-+ FROM_I2C_ENGINE(engine)->original_speed = current_speed;
-+
-+ return true;
-+}
-+/*
-+ * @brief
-+ * Queries in a loop for current engine status
-+ * until retrieved status matches 'expected_result', or timeout occurs.
-+ * Timeout given in microseconds
-+ * and the status query frequency is also one per microsecond.
-+ */
-+enum i2c_channel_operation_result dal_i2c_hw_engine_wait_on_operation_result(
-+ struct i2c_hw_engine *engine,
-+ uint32_t timeout,
-+ enum i2c_channel_operation_result expected_result)
-+{
-+ enum i2c_channel_operation_result result;
-+ uint32_t i = 0;
-+
-+ if (!timeout)
-+ return I2C_CHANNEL_OPERATION_SUCCEEDED;
-+
-+ do {
-+ result = engine->base.funcs->get_channel_status(
-+ &engine->base, NULL);
-+
-+ if (result != expected_result)
-+ break;
-+
-+ dc_service_delay_in_microseconds(engine->base.base.ctx, 1);
-+
-+ ++i;
-+ } while (i < timeout);
-+
-+ return result;
-+}
-+
-+bool dal_i2c_hw_engine_construct(
-+ struct i2c_hw_engine *engine,
-+ struct dc_context *ctx)
-+{
-+ if (!dal_i2c_engine_construct(&engine->base, ctx))
-+ return false;
-+ engine->original_speed = I2CAUX_DEFAULT_I2C_HW_SPEED;
-+ engine->default_speed = I2CAUX_DEFAULT_I2C_HW_SPEED;
-+ return true;
-+}
-+
-+void dal_i2c_hw_engine_destruct(
-+ struct i2c_hw_engine *engine)
-+{
-+ dal_i2c_engine_destruct(&engine->base);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_hw_engine.h b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_hw_engine.h
-new file mode 100644
-index 0000000..5afbd70
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_hw_engine.h
-@@ -0,0 +1,80 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_I2C_HW_ENGINE_H__
-+#define __DAL_I2C_HW_ENGINE_H__
-+
-+enum {
-+ TRANSACTION_TIMEOUT_IN_I2C_CLOCKS = 32
-+};
-+
-+struct i2c_hw_engine;
-+
-+struct i2c_hw_engine_funcs {
-+ uint8_t (*get_hw_buffer_available_size)(
-+ const struct i2c_hw_engine *engine);
-+ enum i2c_channel_operation_result (*wait_on_operation_result)(
-+ struct i2c_hw_engine *engine,
-+ uint32_t timeout,
-+ enum i2c_channel_operation_result expected_result);
-+ uint32_t (*get_transaction_timeout)(
-+ const struct i2c_hw_engine *engine,
-+ uint32_t length);
-+};
-+
-+struct i2c_hw_engine {
-+ struct i2c_engine base;
-+ const struct i2c_hw_engine_funcs *funcs;
-+
-+ /* Values below are in kilohertz */
-+ uint32_t original_speed;
-+ uint32_t default_speed;
-+};
-+
-+bool dal_i2c_hw_engine_construct(
-+ struct i2c_hw_engine *engine,
-+ struct dc_context *ctx);
-+
-+void dal_i2c_hw_engine_destruct(
-+ struct i2c_hw_engine *engine);
-+
-+enum i2c_channel_operation_result dal_i2c_hw_engine_wait_on_operation_result(
-+ struct i2c_hw_engine *engine,
-+ uint32_t timeout,
-+ enum i2c_channel_operation_result expected_result);
-+
-+bool dal_i2c_hw_engine_acquire_engine(
-+ struct i2c_engine *engine,
-+ struct ddc *ddc);
-+
-+bool dal_i2c_hw_engine_submit_request(
-+ struct engine *ptr,
-+ struct i2caux_transaction_request *i2caux_request,
-+ bool middle_of_transaction);
-+
-+enum i2caux_engine_type dal_i2c_hw_engine_get_engine_type(
-+ const struct engine *engine);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_sw_engine.c b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_sw_engine.c
-new file mode 100644
-index 0000000..c253917
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_sw_engine.c
-@@ -0,0 +1,615 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/i2caux_interface.h"
-+#include "engine.h"
-+#include "i2c_engine.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "i2c_sw_engine.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+#define SCL false
-+#define SDA true
-+
-+static inline bool read_bit_from_ddc(
-+ struct ddc *ddc,
-+ bool data_nor_clock)
-+{
-+ uint32_t value = 0;
-+
-+ if (data_nor_clock)
-+ dal_ddc_get_data(ddc, &value);
-+ else
-+ dal_ddc_get_clock(ddc, &value);
-+
-+ return (value != 0);
-+}
-+
-+static inline void write_bit_to_ddc(
-+ struct ddc *ddc,
-+ bool data_nor_clock,
-+ bool bit)
-+{
-+ uint32_t value = bit ? 1 : 0;
-+
-+ if (data_nor_clock)
-+ dal_ddc_set_data(ddc, value);
-+ else
-+ dal_ddc_set_clock(ddc, value);
-+}
-+
-+static bool wait_for_scl_high(
-+ struct dc_context *ctx,
-+ struct ddc *ddc,
-+ uint16_t clock_delay_div_4)
-+{
-+ uint32_t scl_retry = 0;
-+ uint32_t scl_retry_max = I2C_SW_TIMEOUT_DELAY / clock_delay_div_4;
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ /* 3 milliseconds delay
-+ * to wake up some displays from "low power" state.
-+ */
-+
-+ do {
-+ if (read_bit_from_ddc(ddc, SCL))
-+ return true;
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ ++scl_retry;
-+ } while (scl_retry <= scl_retry_max);
-+
-+ return false;
-+}
-+
-+static bool start_sync(
-+ struct dc_context *ctx,
-+ struct ddc *ddc_handle,
-+ uint16_t clock_delay_div_4)
-+{
-+ uint32_t retry = 0;
-+
-+ /* The I2C communications start signal is:
-+ * the SDA going low from high, while the SCL is high. */
-+
-+ write_bit_to_ddc(ddc_handle, SCL, true);
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ do {
-+ write_bit_to_ddc(ddc_handle, SDA, true);
-+
-+ if (!read_bit_from_ddc(ddc_handle, SDA)) {
-+ ++retry;
-+ continue;
-+ }
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ write_bit_to_ddc(ddc_handle, SCL, true);
-+
-+ if (!wait_for_scl_high(ctx, ddc_handle, clock_delay_div_4))
-+ break;
-+
-+ write_bit_to_ddc(ddc_handle, SDA, false);
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ write_bit_to_ddc(ddc_handle, SCL, false);
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ return true;
-+ } while (retry <= I2C_SW_RETRIES);
-+
-+ return false;
-+}
-+
-+static bool stop_sync(
-+ struct dc_context *ctx,
-+ struct ddc *ddc_handle,
-+ uint16_t clock_delay_div_4)
-+{
-+ uint32_t retry = 0;
-+
-+ /* The I2C communications stop signal is:
-+ * the SDA going high from low, while the SCL is high. */
-+
-+ write_bit_to_ddc(ddc_handle, SCL, false);
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ write_bit_to_ddc(ddc_handle, SDA, false);
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ write_bit_to_ddc(ddc_handle, SCL, true);
-+
-+ if (!wait_for_scl_high(ctx, ddc_handle, clock_delay_div_4))
-+ return false;
-+
-+ write_bit_to_ddc(ddc_handle, SDA, true);
-+
-+ do {
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ if (read_bit_from_ddc(ddc_handle, SDA))
-+ return true;
-+
-+ ++retry;
-+ } while (retry <= 2);
-+
-+ return false;
-+}
-+
-+static bool write_byte(
-+ struct dc_context *ctx,
-+ struct ddc *ddc_handle,
-+ uint16_t clock_delay_div_4,
-+ uint8_t byte)
-+{
-+ int32_t shift = 7;
-+ bool ack;
-+
-+ /* bits are transmitted serially, starting from MSB */
-+
-+ do {
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ write_bit_to_ddc(ddc_handle, SDA, (byte >> shift) & 1);
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ write_bit_to_ddc(ddc_handle, SCL, true);
-+
-+ if (!wait_for_scl_high(ctx, ddc_handle, clock_delay_div_4))
-+ return false;
-+
-+ write_bit_to_ddc(ddc_handle, SCL, false);
-+
-+ --shift;
-+ } while (shift >= 0);
-+
-+ /* The display sends ACK by preventing the SDA from going high
-+ * after the SCL pulse we use to send our last data bit.
-+ * If the SDA goes high after that bit, it's a NACK */
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ write_bit_to_ddc(ddc_handle, SDA, true);
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ write_bit_to_ddc(ddc_handle, SCL, true);
-+
-+ if (!wait_for_scl_high(ctx, ddc_handle, clock_delay_div_4))
-+ return false;
-+
-+ /* read ACK bit */
-+
-+ ack = !read_bit_from_ddc(ddc_handle, SDA);
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4 << 1);
-+
-+ write_bit_to_ddc(ddc_handle, SCL, false);
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4 << 1);
-+
-+ return ack;
-+}
-+
-+static bool read_byte(
-+ struct dc_context *ctx,
-+ struct ddc *ddc_handle,
-+ uint16_t clock_delay_div_4,
-+ uint8_t *byte,
-+ bool more)
-+{
-+ int32_t shift = 7;
-+
-+ uint8_t data = 0;
-+
-+ /* The data bits are read from MSB to LSB;
-+ * bit is read while SCL is high */
-+
-+ do {
-+ write_bit_to_ddc(ddc_handle, SCL, true);
-+
-+ if (!wait_for_scl_high(ctx, ddc_handle, clock_delay_div_4))
-+ return false;
-+
-+ if (read_bit_from_ddc(ddc_handle, SDA))
-+ data |= (1 << shift);
-+
-+ write_bit_to_ddc(ddc_handle, SCL, false);
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4 << 1);
-+
-+ --shift;
-+ } while (shift >= 0);
-+
-+ /* read only whole byte */
-+
-+ *byte = data;
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ /* send the acknowledge bit:
-+ * SDA low means ACK, SDA high means NACK */
-+
-+ write_bit_to_ddc(ddc_handle, SDA, !more);
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ write_bit_to_ddc(ddc_handle, SCL, true);
-+
-+ if (!wait_for_scl_high(ctx, ddc_handle, clock_delay_div_4))
-+ return false;
-+
-+ write_bit_to_ddc(ddc_handle, SCL, false);
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ write_bit_to_ddc(ddc_handle, SDA, true);
-+
-+ dc_service_delay_in_microseconds(ctx, clock_delay_div_4);
-+
-+ return true;
-+}
-+
-+static bool i2c_write(
-+ struct dc_context *ctx,
-+ struct ddc *ddc_handle,
-+ uint16_t clock_delay_div_4,
-+ uint8_t address,
-+ uint8_t length,
-+ const uint8_t *data)
-+{
-+ uint32_t i = 0;
-+
-+ if (!write_byte(ctx, ddc_handle, clock_delay_div_4, address))
-+ return false;
-+
-+ while (i < length) {
-+ if (!write_byte(ctx, ddc_handle, clock_delay_div_4, data[i]))
-+ return false;
-+ ++i;
-+ }
-+
-+ return true;
-+}
-+
-+static bool i2c_read(
-+ struct dc_context *ctx,
-+ struct ddc *ddc_handle,
-+ uint16_t clock_delay_div_4,
-+ uint8_t address,
-+ uint8_t length,
-+ uint8_t *data)
-+{
-+ uint32_t i = 0;
-+
-+ if (!write_byte(ctx, ddc_handle, clock_delay_div_4, address))
-+ return false;
-+
-+ while (i < length) {
-+ if (!read_byte(ctx, ddc_handle, clock_delay_div_4, data + i,
-+ i < length - 1))
-+ return false;
-+ ++i;
-+ }
-+
-+ return true;
-+}
-+
-+/*
-+ * @brief
-+ * Cast 'struct i2c_engine *'
-+ * to 'struct i2c_sw_engine *'
-+ */
-+#define FROM_I2C_ENGINE(ptr) \
-+ container_of((ptr), struct i2c_sw_engine, base)
-+
-+/*
-+ * @brief
-+ * Cast 'struct engine *'
-+ * to 'struct i2c_sw_engine *'
-+ */
-+#define FROM_ENGINE(ptr) \
-+ FROM_I2C_ENGINE(container_of((ptr), struct i2c_engine, base))
-+
-+enum i2caux_engine_type dal_i2c_sw_engine_get_engine_type(
-+ const struct engine *engine)
-+{
-+ return I2CAUX_ENGINE_TYPE_I2C_SW;
-+}
-+
-+bool dal_i2c_sw_engine_submit_request(
-+ struct engine *engine,
-+ struct i2caux_transaction_request *i2caux_request,
-+ bool middle_of_transaction)
-+{
-+ struct i2c_sw_engine *sw_engine = FROM_ENGINE(engine);
-+
-+ struct i2c_engine *base = &sw_engine->base;
-+
-+ struct i2c_request_transaction_data request;
-+ bool operation_succeeded = false;
-+
-+ if (i2caux_request->operation == I2CAUX_TRANSACTION_READ)
-+ request.action = middle_of_transaction ?
-+ I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT :
-+ I2CAUX_TRANSACTION_ACTION_I2C_READ;
-+ else if (i2caux_request->operation == I2CAUX_TRANSACTION_WRITE)
-+ request.action = middle_of_transaction ?
-+ I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT :
-+ I2CAUX_TRANSACTION_ACTION_I2C_WRITE;
-+ else {
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_INVALID_OPERATION;
-+ /* in DAL2, there was no "return false" */
-+ return false;
-+ }
-+
-+ request.address = (uint8_t)i2caux_request->payload.address;
-+ request.length = i2caux_request->payload.length;
-+ request.data = i2caux_request->payload.data;
-+
-+ base->funcs->submit_channel_request(base, &request);
-+
-+ if ((request.status == I2C_CHANNEL_OPERATION_ENGINE_BUSY) ||
-+ (request.status == I2C_CHANNEL_OPERATION_FAILED))
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_CHANNEL_BUSY;
-+ else {
-+ enum i2c_channel_operation_result operation_result;
-+
-+ do {
-+ operation_result =
-+ base->funcs->get_channel_status(base, NULL);
-+
-+ switch (operation_result) {
-+ case I2C_CHANNEL_OPERATION_SUCCEEDED:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_SUCCEEDED;
-+ operation_succeeded = true;
-+ break;
-+ case I2C_CHANNEL_OPERATION_NO_RESPONSE:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_NACK;
-+ break;
-+ case I2C_CHANNEL_OPERATION_TIMEOUT:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_TIMEOUT;
-+ break;
-+ case I2C_CHANNEL_OPERATION_FAILED:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_INCOMPLETE;
-+ break;
-+ default:
-+ i2caux_request->status =
-+ I2CAUX_TRANSACTION_STATUS_FAILED_OPERATION;
-+ break;
-+ }
-+ } while (operation_result == I2C_CHANNEL_OPERATION_ENGINE_BUSY);
-+ }
-+
-+ return operation_succeeded;
-+}
-+
-+uint32_t dal_i2c_sw_engine_get_speed(
-+ const struct i2c_engine *engine)
-+{
-+ return FROM_I2C_ENGINE(engine)->speed;
-+}
-+
-+void dal_i2c_sw_engine_set_speed(
-+ struct i2c_engine *engine,
-+ uint32_t speed)
-+{
-+ struct i2c_sw_engine *sw_engine = FROM_I2C_ENGINE(engine);
-+
-+ ASSERT(speed);
-+
-+ sw_engine->speed = speed ? speed : I2CAUX_DEFAULT_I2C_SW_SPEED;
-+
-+ sw_engine->clock_delay = 1000 / sw_engine->speed;
-+
-+ if (sw_engine->clock_delay < 12)
-+ sw_engine->clock_delay = 12;
-+}
-+
-+bool dal_i2caux_i2c_sw_engine_acquire_engine(
-+ struct i2c_engine *engine,
-+ struct ddc *ddc)
-+{
-+ enum gpio_result result;
-+
-+ result = dal_ddc_open(ddc, GPIO_MODE_FAST_OUTPUT,
-+ GPIO_DDC_CONFIG_TYPE_MODE_I2C);
-+
-+ if (result != GPIO_RESULT_OK)
-+ return false;
-+
-+ engine->base.ddc = ddc;
-+
-+ return true;
-+}
-+
-+void dal_i2c_sw_engine_submit_channel_request(
-+ struct i2c_engine *engine,
-+ struct i2c_request_transaction_data *req)
-+{
-+ struct i2c_sw_engine *sw_engine = FROM_I2C_ENGINE(engine);
-+
-+ struct ddc *ddc = engine->base.ddc;
-+ uint16_t clock_delay_div_4 = sw_engine->clock_delay >> 2;
-+
-+ /* send sync (start / repeated start) */
-+
-+ bool result = start_sync(engine->base.ctx, ddc, clock_delay_div_4);
-+
-+ /* process payload */
-+
-+ if (result) {
-+ switch (req->action) {
-+ case I2CAUX_TRANSACTION_ACTION_I2C_WRITE:
-+ case I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT:
-+ result = i2c_write(engine->base.ctx, ddc, clock_delay_div_4,
-+ req->address, req->length, req->data);
-+ break;
-+ case I2CAUX_TRANSACTION_ACTION_I2C_READ:
-+ case I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT:
-+ result = i2c_read(engine->base.ctx, ddc, clock_delay_div_4,
-+ req->address, req->length, req->data);
-+ break;
-+ default:
-+ result = false;
-+ break;
-+ }
-+ }
-+
-+ /* send stop if not 'mot' or operation failed */
-+
-+ if (!result ||
-+ (req->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE) ||
-+ (req->action == I2CAUX_TRANSACTION_ACTION_I2C_READ))
-+ if (!stop_sync(engine->base.ctx, ddc, clock_delay_div_4))
-+ result = false;
-+
-+ req->status = result ?
-+ I2C_CHANNEL_OPERATION_SUCCEEDED :
-+ I2C_CHANNEL_OPERATION_FAILED;
-+}
-+
-+enum i2c_channel_operation_result dal_i2c_sw_engine_get_channel_status(
-+ struct i2c_engine *engine,
-+ uint8_t *returned_bytes)
-+{
-+ return dal_ddc_check_line_aborted(engine->base.ddc) ?
-+ I2C_CHANNEL_OPERATION_FAILED :
-+ I2C_CHANNEL_OPERATION_SUCCEEDED;
-+}
-+
-+void dal_i2c_sw_engine_destruct(
-+ struct i2c_sw_engine *engine)
-+{
-+ dal_i2c_engine_destruct(&engine->base);
-+}
-+
-+static void destroy(
-+ struct i2c_engine **ptr)
-+{
-+ dal_i2c_sw_engine_destruct(FROM_I2C_ENGINE(*ptr));
-+
-+ dc_service_free((*ptr)->base.ctx, *ptr);
-+ *ptr = NULL;
-+}
-+
-+static const struct i2c_engine_funcs i2c_engine_funcs = {
-+ .acquire_engine = dal_i2caux_i2c_sw_engine_acquire_engine,
-+ .destroy = destroy,
-+ .get_speed = dal_i2c_sw_engine_get_speed,
-+ .set_speed = dal_i2c_sw_engine_set_speed,
-+ .setup_engine = dal_i2c_engine_setup_i2c_engine,
-+ .submit_channel_request = dal_i2c_sw_engine_submit_channel_request,
-+ .process_channel_reply = dal_i2c_engine_process_channel_reply,
-+ .get_channel_status = dal_i2c_sw_engine_get_channel_status,
-+};
-+
-+static void release_engine(
-+ struct engine *engine)
-+{
-+
-+}
-+
-+static const struct engine_funcs engine_funcs = {
-+ .release_engine = release_engine,
-+ .get_engine_type = dal_i2c_sw_engine_get_engine_type,
-+ .acquire = dal_i2c_engine_acquire,
-+ .submit_request = dal_i2c_sw_engine_submit_request,
-+ .keep_power_up_count = dal_i2caux_keep_power_up_count,
-+};
-+
-+bool dal_i2c_sw_engine_construct(
-+ struct i2c_sw_engine *engine,
-+ const struct i2c_sw_engine_create_arg *arg)
-+{
-+ if (!dal_i2c_engine_construct(&engine->base, arg->ctx))
-+ return false;
-+
-+ dal_i2c_sw_engine_set_speed(&engine->base, arg->default_speed);
-+ engine->base.funcs = &i2c_engine_funcs;
-+ engine->base.base.funcs = &engine_funcs;
-+ return true;
-+}
-+
-+
-+
-+struct i2c_engine *dal_i2c_sw_engine_create(
-+ const struct i2c_sw_engine_create_arg *arg)
-+{
-+ struct i2c_sw_engine *engine;
-+
-+ if (!arg) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ engine = dc_service_alloc(arg->ctx, sizeof(struct i2c_sw_engine));
-+
-+ if (!engine) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ if (dal_i2c_sw_engine_construct(engine, arg))
-+ return &engine->base;
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ dc_service_free(arg->ctx, engine);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_sw_engine.h b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_sw_engine.h
-new file mode 100644
-index 0000000..e0cb4c3
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/i2c_sw_engine.h
-@@ -0,0 +1,81 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_I2C_SW_ENGINE_H__
-+#define __DAL_I2C_SW_ENGINE_H__
-+
-+enum {
-+ I2C_SW_RETRIES = 10,
-+ I2C_SW_SCL_READ_RETRIES = 128,
-+ /* following value is in microseconds */
-+ I2C_SW_TIMEOUT_DELAY = 3000
-+};
-+
-+struct i2c_sw_engine;
-+
-+struct i2c_sw_engine {
-+ struct i2c_engine base;
-+ uint32_t clock_delay;
-+ /* Values below are in KHz */
-+ uint32_t speed;
-+ uint32_t default_speed;
-+};
-+
-+struct i2c_sw_engine_create_arg {
-+ uint32_t default_speed;
-+ struct dc_context *ctx;
-+};
-+
-+bool dal_i2c_sw_engine_construct(
-+ struct i2c_sw_engine *engine,
-+ const struct i2c_sw_engine_create_arg *arg);
-+
-+bool dal_i2caux_i2c_sw_engine_acquire_engine(
-+ struct i2c_engine *engine,
-+ struct ddc *ddc_handle);
-+
-+void dal_i2c_sw_engine_destruct(
-+ struct i2c_sw_engine *engine);
-+
-+struct i2c_engine *dal_i2c_sw_engine_create(
-+ const struct i2c_sw_engine_create_arg *arg);
-+enum i2caux_engine_type dal_i2c_sw_engine_get_engine_type(
-+ const struct engine *engine);
-+bool dal_i2c_sw_engine_submit_request(
-+ struct engine *ptr,
-+ struct i2caux_transaction_request *i2caux_request,
-+ bool middle_of_transaction);
-+uint32_t dal_i2c_sw_engine_get_speed(
-+ const struct i2c_engine *engine);
-+void dal_i2c_sw_engine_set_speed(
-+ struct i2c_engine *ptr,
-+ uint32_t speed);
-+void dal_i2c_sw_engine_submit_channel_request(
-+ struct i2c_engine *ptr,
-+ struct i2c_request_transaction_data *req);
-+enum i2c_channel_operation_result dal_i2c_sw_engine_get_channel_status(
-+ struct i2c_engine *engine,
-+ uint8_t *returned_bytes);
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c b/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c
-new file mode 100644
-index 0000000..50262a4
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c
-@@ -0,0 +1,519 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "include/i2caux_interface.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "i2caux.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+#include "engine.h"
-+#include "i2c_engine.h"
-+#include "aux_engine.h"
-+
-+/*
-+ * This unit
-+ */
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+#include "dce110/i2caux_dce110.h"
-+#endif
-+
-+/*
-+ * @brief
-+ * Plain API, available publicly
-+ */
-+
-+struct i2caux *dal_i2caux_create(
-+ struct adapter_service *as,
-+ struct dc_context *ctx)
-+{
-+ enum dce_version dce_version;
-+
-+ if (!as) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ dce_version = dal_adapter_service_get_dce_version(as);
-+
-+ switch (dce_version) {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ case DCE_VERSION_11_0:
-+ return dal_i2caux_dce110_create(as, ctx);
-+#endif
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+}
-+
-+bool dal_i2caux_submit_i2c_command(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc,
-+ struct i2c_command *cmd)
-+{
-+ struct i2c_engine *engine;
-+ uint8_t index_of_payload = 0;
-+ bool result;
-+
-+ if (!ddc) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!cmd) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ switch (cmd->engine) {
-+ case I2C_COMMAND_ENGINE_SW:
-+ /* try to acquire SW engine first,
-+ * acquire HW engine if SW engine not available */
-+ engine = i2caux->funcs->acquire_i2c_sw_engine(i2caux, ddc);
-+
-+ if (!engine)
-+ engine = i2caux->funcs->acquire_i2c_hw_engine(
-+ i2caux, ddc);
-+ break;
-+ case I2C_COMMAND_ENGINE_HW:
-+ case I2C_COMMAND_ENGINE_DEFAULT:
-+ default:
-+ /* try to acquire HW engine first,
-+ * acquire SW engine if HW engine not available */
-+ engine = i2caux->funcs->acquire_i2c_hw_engine(i2caux, ddc);
-+
-+ if (!engine)
-+ engine = i2caux->funcs->acquire_i2c_sw_engine(
-+ i2caux, ddc);
-+ }
-+
-+ if (!engine)
-+ return false;
-+
-+ engine->funcs->set_speed(engine, cmd->speed);
-+
-+ result = true;
-+
-+ while (index_of_payload < cmd->number_of_payloads) {
-+ bool mot = (index_of_payload != cmd->number_of_payloads - 1);
-+
-+ struct i2c_payload *payload = cmd->payloads + index_of_payload;
-+
-+ struct i2caux_transaction_request request = { 0 };
-+
-+ request.operation = payload->write ?
-+ I2CAUX_TRANSACTION_WRITE :
-+ I2CAUX_TRANSACTION_READ;
-+
-+ request.payload.address_space =
-+ I2CAUX_TRANSACTION_ADDRESS_SPACE_I2C;
-+ request.payload.address = (payload->address << 1) |
-+ !payload->write;
-+ request.payload.length = payload->length;
-+ request.payload.data = payload->data;
-+
-+ if (!engine->base.funcs->submit_request(
-+ &engine->base, &request, mot)) {
-+ result = false;
-+ break;
-+ }
-+
-+ ++index_of_payload;
-+ }
-+
-+ i2caux->funcs->release_engine(i2caux, &engine->base);
-+
-+ return result;
-+}
-+
-+bool dal_i2caux_submit_aux_command(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc,
-+ struct aux_command *cmd)
-+{
-+ struct aux_engine *engine;
-+ uint8_t index_of_payload = 0;
-+ bool result;
-+
-+ if (!ddc) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!cmd) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ engine = i2caux->funcs->acquire_aux_engine(i2caux, ddc);
-+
-+ if (!engine)
-+ return false;
-+
-+ engine->delay = cmd->defer_delay;
-+ engine->max_defer_write_retry = cmd->max_defer_write_retry;
-+
-+ result = true;
-+
-+ while (index_of_payload < cmd->number_of_payloads) {
-+ bool mot = (index_of_payload != cmd->number_of_payloads - 1);
-+
-+ struct aux_payload *payload = cmd->payloads + index_of_payload;
-+
-+ struct i2caux_transaction_request request = { 0 };
-+
-+ request.operation = payload->write ?
-+ I2CAUX_TRANSACTION_WRITE :
-+ I2CAUX_TRANSACTION_READ;
-+
-+ if (payload->i2c_over_aux) {
-+ request.payload.address_space =
-+ I2CAUX_TRANSACTION_ADDRESS_SPACE_I2C;
-+
-+ request.payload.address = (payload->address << 1) |
-+ !payload->write;
-+ } else {
-+ request.payload.address_space =
-+ I2CAUX_TRANSACTION_ADDRESS_SPACE_DPCD;
-+
-+ request.payload.address = payload->address;
-+ }
-+
-+ request.payload.length = payload->length;
-+ request.payload.data = payload->data;
-+
-+ if (!engine->base.funcs->submit_request(
-+ &engine->base, &request, mot)) {
-+ result = false;
-+ break;
-+ }
-+
-+ ++index_of_payload;
-+ }
-+
-+ i2caux->funcs->release_engine(i2caux, &engine->base);
-+
-+ return result;
-+}
-+
-+static bool get_hw_supported_ddc_line(
-+ struct ddc *ddc,
-+ enum gpio_ddc_line *line)
-+{
-+ enum gpio_ddc_line line_found;
-+
-+ if (!ddc) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!dal_ddc_is_hw_supported(ddc))
-+ return false;
-+
-+ line_found = dal_ddc_get_line(ddc);
-+
-+ if (line_found >= GPIO_DDC_LINE_COUNT)
-+ return false;
-+
-+ *line = line_found;
-+
-+ return true;
-+}
-+
-+void dal_i2caux_keep_engine_power_up(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc,
-+ bool keep_power_up)
-+{
-+ enum gpio_ddc_line line;
-+ struct i2c_engine *engine;
-+
-+ if (!get_hw_supported_ddc_line(ddc, &line))
-+ return;
-+
-+ engine = i2caux->i2c_hw_engines[line];
-+
-+ engine->base.funcs->keep_power_up_count(&engine->base, keep_power_up);
-+}
-+
-+bool dal_i2caux_start_gtc_sync(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc)
-+{
-+ enum gpio_ddc_line line;
-+
-+ struct aux_engine *engine;
-+
-+ bool result;
-+
-+ if (!get_hw_supported_ddc_line(ddc, &line))
-+ return false;
-+
-+ engine = i2caux->aux_engines[line];
-+
-+ if (!engine)
-+ return false;
-+
-+ if (!engine->base.funcs->acquire(&engine->base, ddc))
-+ return false;
-+
-+ result = engine->funcs->start_gtc_sync(engine);
-+
-+ i2caux->funcs->release_engine(i2caux, &engine->base);
-+
-+ return result;
-+}
-+
-+bool dal_i2caux_stop_gtc_sync(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc)
-+{
-+ enum gpio_ddc_line line;
-+
-+ struct aux_engine *engine;
-+
-+ if (!get_hw_supported_ddc_line(ddc, &line))
-+ return false;
-+
-+ engine = i2caux->aux_engines[line];
-+
-+ if (!engine)
-+ return false;
-+
-+ if (!engine->base.funcs->acquire(&engine->base, ddc))
-+ return false;
-+
-+ engine->funcs->stop_gtc_sync(engine);
-+
-+ i2caux->funcs->release_engine(i2caux, &engine->base);
-+
-+ return true;
-+}
-+
-+void dal_i2caux_configure_aux(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc,
-+ union aux_config cfg)
-+{
-+ struct aux_engine *engine =
-+ i2caux->funcs->acquire_aux_engine(i2caux, ddc);
-+
-+ if (!engine)
-+ return;
-+
-+ engine->funcs->configure(engine, cfg);
-+
-+ i2caux->funcs->release_engine(i2caux, &engine->base);
-+}
-+
-+void dal_i2caux_destroy(
-+ struct i2caux **i2caux)
-+{
-+ if (!i2caux || !*i2caux) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ (*i2caux)->funcs->destroy(i2caux);
-+
-+ *i2caux = NULL;
-+}
-+
-+/*
-+ * @brief
-+ * An utility function used by 'struct i2caux' and its descendants
-+ */
-+
-+uint32_t dal_i2caux_get_reference_clock(
-+ struct adapter_service *as)
-+{
-+ struct firmware_info info = { { 0 } };
-+
-+ if (!dal_adapter_service_get_firmware_info(as, &info))
-+ return 0;
-+
-+ return info.pll_info.crystal_frequency;
-+}
-+
-+/*
-+ * @brief
-+ * i2caux
-+ */
-+
-+enum {
-+ /* following are expressed in KHz */
-+ DEFAULT_I2C_SW_SPEED = 50,
-+ DEFAULT_I2C_HW_SPEED = 50,
-+
-+ /* This is the timeout as defined in DP 1.2a,
-+ * 2.3.4 "Detailed uPacket TX AUX CH State Description". */
-+ AUX_TIMEOUT_PERIOD = 400,
-+
-+ /* Ideally, the SW timeout should be just above 550usec
-+ * which is programmed in HW.
-+ * But the SW timeout of 600usec is not reliable,
-+ * because on some systems, delay_in_microseconds()
-+ * returns faster than it should.
-+ * EPR #379763: by trial-and-error on different systems,
-+ * 700usec is the minimum reliable SW timeout for polling
-+ * the AUX_SW_STATUS.AUX_SW_DONE bit.
-+ * This timeout expires *only* when there is
-+ * AUX Error or AUX Timeout conditions - not during normal operation.
-+ * During normal operation, AUX_SW_STATUS.AUX_SW_DONE bit is set
-+ * at most within ~240usec. That means,
-+ * increasing this timeout will not affect normal operation,
-+ * and we'll timeout after
-+ * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD = 1600usec.
-+ * This timeout is especially important for
-+ * resume from S3 and CTS. */
-+ SW_AUX_TIMEOUT_PERIOD_MULTIPLIER = 4
-+};
-+
-+struct i2c_engine *dal_i2caux_acquire_i2c_sw_engine(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc)
-+{
-+ enum gpio_ddc_line line;
-+ struct i2c_engine *engine = NULL;
-+
-+ if (get_hw_supported_ddc_line(ddc, &line))
-+ engine = i2caux->i2c_sw_engines[line];
-+
-+ if (!engine)
-+ engine = i2caux->i2c_generic_sw_engine;
-+
-+ if (!engine)
-+ return NULL;
-+
-+ if (!engine->base.funcs->acquire(&engine->base, ddc))
-+ return NULL;
-+
-+ return engine;
-+}
-+
-+struct aux_engine *dal_i2caux_acquire_aux_engine(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc)
-+{
-+ enum gpio_ddc_line line;
-+ struct aux_engine *engine;
-+
-+ if (!get_hw_supported_ddc_line(ddc, &line))
-+ return NULL;
-+
-+ engine = i2caux->aux_engines[line];
-+
-+ if (!engine)
-+ return NULL;
-+
-+ if (!engine->base.funcs->acquire(&engine->base, ddc))
-+ return NULL;
-+
-+ return engine;
-+}
-+
-+void dal_i2caux_release_engine(
-+ struct i2caux *i2caux,
-+ struct engine *engine)
-+{
-+ engine->funcs->release_engine(engine);
-+
-+ dal_ddc_close(engine->ddc);
-+
-+ engine->ddc = NULL;
-+}
-+
-+bool dal_i2caux_construct(
-+ struct i2caux *i2caux,
-+ struct adapter_service *as,
-+ struct dc_context *ctx)
-+{
-+ uint32_t i = 0;
-+
-+ i2caux->ctx = ctx;
-+ do {
-+ i2caux->i2c_sw_engines[i] = NULL;
-+ i2caux->i2c_hw_engines[i] = NULL;
-+ i2caux->aux_engines[i] = NULL;
-+
-+ ++i;
-+ } while (i < GPIO_DDC_LINE_COUNT);
-+
-+ i2caux->i2c_generic_sw_engine = NULL;
-+ i2caux->i2c_generic_hw_engine = NULL;
-+
-+ i2caux->aux_timeout_period =
-+ SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD;
-+
-+ i2caux->default_i2c_sw_speed = DEFAULT_I2C_SW_SPEED;
-+ i2caux->default_i2c_hw_speed = DEFAULT_I2C_HW_SPEED;
-+
-+ return true;
-+}
-+
-+void dal_i2caux_destruct(
-+ struct i2caux *i2caux)
-+{
-+ uint32_t i = 0;
-+
-+ if (i2caux->i2c_generic_hw_engine)
-+ i2caux->i2c_generic_hw_engine->funcs->destroy(
-+ &i2caux->i2c_generic_hw_engine);
-+
-+ if (i2caux->i2c_generic_sw_engine)
-+ i2caux->i2c_generic_sw_engine->funcs->destroy(
-+ &i2caux->i2c_generic_sw_engine);
-+
-+ do {
-+ if (i2caux->aux_engines[i])
-+ i2caux->aux_engines[i]->funcs->destroy(
-+ &i2caux->aux_engines[i]);
-+
-+ if (i2caux->i2c_hw_engines[i])
-+ i2caux->i2c_hw_engines[i]->funcs->destroy(
-+ &i2caux->i2c_hw_engines[i]);
-+
-+ if (i2caux->i2c_sw_engines[i])
-+ i2caux->i2c_sw_engines[i]->funcs->destroy(
-+ &i2caux->i2c_sw_engines[i]);
-+
-+ ++i;
-+ } while (i < GPIO_DDC_LINE_COUNT);
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.h b/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.h
-new file mode 100644
-index 0000000..76f5b63
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.h
-@@ -0,0 +1,123 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_I2C_AUX_H__
-+#define __DAL_I2C_AUX_H__
-+
-+uint32_t dal_i2caux_get_reference_clock(
-+ struct adapter_service *as);
-+
-+struct i2caux;
-+
-+struct engine;
-+
-+struct i2caux_funcs {
-+ void (*destroy)(struct i2caux **ptr);
-+ struct i2c_engine * (*acquire_i2c_sw_engine)(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc);
-+ struct i2c_engine * (*acquire_i2c_hw_engine)(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc);
-+ struct aux_engine * (*acquire_aux_engine)(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc);
-+ void (*release_engine)(
-+ struct i2caux *i2caux,
-+ struct engine *engine);
-+};
-+
-+struct i2c_engine;
-+struct aux_engine;
-+
-+struct i2caux {
-+ struct dc_context *ctx;
-+ const struct i2caux_funcs *funcs;
-+ /* On ASIC we have certain amount of lines with HW DDC engine
-+ * (4, 6, or maybe more in the future).
-+ * For every such line, we create separate HW DDC engine
-+ * (since we have these engines in HW) and separate SW DDC engine
-+ * (to allow concurrent use of few lines).
-+ * In similar way we have AUX engines. */
-+
-+ /* I2C SW engines, per DDC line.
-+ * Only lines with HW DDC support will be initialized */
-+ struct i2c_engine *i2c_sw_engines[GPIO_DDC_LINE_COUNT];
-+
-+ /* I2C HW engines, per DDC line.
-+ * Only lines with HW DDC support will be initialized */
-+ struct i2c_engine *i2c_hw_engines[GPIO_DDC_LINE_COUNT];
-+
-+ /* AUX engines, per DDC line.
-+ * Only lines with HW AUX support will be initialized */
-+ struct aux_engine *aux_engines[GPIO_DDC_LINE_COUNT];
-+
-+ /* For all other lines, we can use
-+ * single instance of generic I2C HW engine
-+ * (since in HW, there is single instance of it)
-+ * or single instance of generic I2C SW engine.
-+ * AUX is not supported for other lines. */
-+
-+ /* General-purpose I2C SW engine.
-+ * Can be assigned dynamically to any line per transaction */
-+ struct i2c_engine *i2c_generic_sw_engine;
-+
-+ /* General-purpose I2C generic HW engine.
-+ * Can be assigned dynamically to almost any line per transaction */
-+ struct i2c_engine *i2c_generic_hw_engine;
-+
-+ /* [anaumov] in DAL2, there is a Mutex */
-+
-+ uint32_t aux_timeout_period;
-+
-+ /* expressed in KHz */
-+ uint32_t default_i2c_sw_speed;
-+ uint32_t default_i2c_hw_speed;
-+};
-+
-+bool dal_i2caux_construct(
-+ struct i2caux *i2caux,
-+ struct adapter_service *as,
-+ struct dc_context *ctx);
-+
-+void dal_i2caux_release_engine(
-+ struct i2caux *i2caux,
-+ struct engine *engine);
-+
-+void dal_i2caux_destruct(
-+ struct i2caux *i2caux);
-+
-+void dal_i2caux_destroy(
-+ struct i2caux **ptr);
-+
-+struct i2c_engine *dal_i2caux_acquire_i2c_sw_engine(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc);
-+
-+struct aux_engine *dal_i2caux_acquire_aux_engine(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h b/drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h
-new file mode 100644
-index 0000000..f7315c6
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h
-@@ -0,0 +1,463 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+/**
-+ * Bandwidth and Watermark calculations interface.
-+ * (Refer to "DCE11_mode_support.xlsm" from Perforce.)
-+ */
-+#ifndef __BANDWIDTH_CALCS_H__
-+#define __BANDWIDTH_CALCS_H__
-+
-+#include "bw_fixed.h"
-+/*******************************************************************************
-+ * There are three types of input into Calculations:
-+ * 1. per-DCE static values - these are "hardcoded" properties of the DCEIP
-+ * 2. board-level values - these are generally coming from VBIOS parser
-+ * 3. mode/configuration values - depending Mode, Scaling number of Displays etc.
-+ ******************************************************************************/
-+
-+enum bw_stereo_mode {
-+ mono,
-+ side_by_side,
-+ top_bottom
-+};
-+
-+enum bw_ul_mode {
-+ ul_none,
-+ ul_only,
-+ ul_blend
-+};
-+
-+enum bw_tiling_mode {
-+ linear,
-+ tiled
-+};
-+
-+enum bw_panning_and_bezel_adj {
-+ none,
-+ any_lines
-+};
-+
-+enum bw_underlay_surface_type {
-+ yuv_420,
-+ yuv_422
-+};
-+
-+struct bw_calcs_input_dceip {
-+ struct bw_fixed dmif_request_buffer_size;
-+ struct bw_fixed de_tiling_buffer;
-+ struct bw_fixed dcfclk_request_generation;
-+ struct bw_fixed lines_interleaved_into_lb;
-+ struct bw_fixed chunk_width;
-+ struct bw_fixed number_of_graphics_pipes;
-+ struct bw_fixed number_of_underlay_pipes;
-+ bool display_write_back_supported;
-+ bool argb_compression_support;
-+ struct bw_fixed underlay_vscaler_efficiency6_bit_per_component;
-+ struct bw_fixed underlay_vscaler_efficiency8_bit_per_component;
-+ struct bw_fixed underlay_vscaler_efficiency10_bit_per_component;
-+ struct bw_fixed underlay_vscaler_efficiency12_bit_per_component;
-+ struct bw_fixed graphics_vscaler_efficiency6_bit_per_component;
-+ struct bw_fixed graphics_vscaler_efficiency8_bit_per_component;
-+ struct bw_fixed graphics_vscaler_efficiency10_bit_per_component;
-+ struct bw_fixed graphics_vscaler_efficiency12_bit_per_component;
-+ struct bw_fixed alpha_vscaler_efficiency;
-+ struct bw_fixed max_dmif_buffer_allocated;
-+ struct bw_fixed graphics_dmif_size;
-+ struct bw_fixed underlay_luma_dmif_size;
-+ struct bw_fixed underlay_chroma_dmif_size;
-+ bool pre_downscaler_enabled;
-+ bool underlay_downscale_prefetch_enabled;
-+ struct bw_fixed lb_write_pixels_per_dispclk;
-+ struct bw_fixed lb_size_per_component444;
-+ bool graphics_lb_nodownscaling_multi_line_prefetching;
-+ struct bw_fixed stutter_and_dram_clock_state_change_gated_before_cursor;
-+ struct bw_fixed underlay420_luma_lb_size_per_component;
-+ struct bw_fixed underlay420_chroma_lb_size_per_component;
-+ struct bw_fixed underlay422_lb_size_per_component;
-+ struct bw_fixed cursor_chunk_width;
-+ struct bw_fixed cursor_dcp_buffer_lines;
-+ struct bw_fixed cursor_memory_interface_buffer_pixels;
-+ struct bw_fixed underlay_maximum_width_efficient_for_tiling;
-+ struct bw_fixed underlay_maximum_height_efficient_for_tiling;
-+ struct bw_fixed peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display;
-+ struct bw_fixed peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation;
-+ struct bw_fixed minimum_outstanding_pte_request_limit;
-+ struct bw_fixed maximum_total_outstanding_pte_requests_allowed_by_saw;
-+ bool limit_excessive_outstanding_dmif_requests;
-+ struct bw_fixed linear_mode_line_request_alternation_slice;
-+ struct bw_fixed scatter_gather_lines_of_pte_prefetching_in_linear_mode;
-+ struct bw_fixed display_write_back420_luma_mcifwr_buffer_size;
-+ struct bw_fixed display_write_back420_chroma_mcifwr_buffer_size;
-+ struct bw_fixed request_efficiency;
-+ struct bw_fixed dispclk_per_request;
-+ struct bw_fixed dispclk_ramping_factor;
-+ struct bw_fixed display_pipe_throughput_factor;
-+ struct bw_fixed scatter_gather_pte_request_rows_in_tiling_mode;
-+ struct bw_fixed mcifwr_all_surfaces_burst_time; /* 0 todo: this is a bug*/
-+};
-+
-+struct bw_calcs_input_vbios {
-+ struct bw_fixed dram_channel_width_in_bits;
-+ struct bw_fixed number_of_dram_channels;
-+ struct bw_fixed number_of_dram_banks;
-+ struct bw_fixed high_yclk;
-+ struct bw_fixed high_dram_bandwidth_per_channel;
-+ struct bw_fixed low_yclk;
-+ struct bw_fixed low_dram_bandwidth_per_channel;
-+ struct bw_fixed low_sclk;
-+ struct bw_fixed mid_sclk;
-+ struct bw_fixed high_sclk;
-+ struct bw_fixed low_voltage_max_dispclk;
-+ struct bw_fixed mid_voltage_max_dispclk;
-+ struct bw_fixed high_voltage_max_dispclk;
-+ struct bw_fixed data_return_bus_width;
-+ struct bw_fixed trc;
-+ struct bw_fixed dmifmc_urgent_latency;
-+ struct bw_fixed stutter_self_refresh_exit_latency;
-+ struct bw_fixed nbp_state_change_latency;
-+ struct bw_fixed mcifwrmc_urgent_latency;
-+ bool scatter_gather_enable;
-+ struct bw_fixed down_spread_percentage;
-+ struct bw_fixed cursor_width;
-+ struct bw_fixed average_compression_rate;
-+ struct bw_fixed number_of_request_slots_gmc_reserves_for_dmif_per_channel;
-+ struct bw_fixed blackout_duration;
-+ struct bw_fixed maximum_blackout_recovery_time;
-+};
-+
-+struct bw_calcs_input_mode_data_internal {
-+ /* data for all displays */
-+ uint32_t number_of_displays;
-+ struct bw_fixed graphics_rotation_angle;
-+ struct bw_fixed underlay_rotation_angle;
-+ bool display_synchronization_enabled;
-+ enum bw_underlay_surface_type underlay_surface_type;
-+ enum bw_panning_and_bezel_adj panning_and_bezel_adjustment;
-+ enum bw_tiling_mode graphics_tiling_mode;
-+ bool graphics_interlace_mode;
-+ struct bw_fixed graphics_bytes_per_pixel;
-+ struct bw_fixed graphics_htaps;
-+ struct bw_fixed graphics_vtaps;
-+ struct bw_fixed graphics_lb_bpc;
-+ struct bw_fixed underlay_lb_bpc;
-+ enum bw_tiling_mode underlay_tiling_mode;
-+ struct bw_fixed underlay_htaps;
-+ struct bw_fixed underlay_vtaps;
-+ struct bw_fixed underlay_src_width;
-+ struct bw_fixed underlay_src_height;
-+ struct bw_fixed underlay_pitch_in_pixels;
-+ enum bw_stereo_mode underlay_stereo_mode;
-+ bool d0_fbc_enable;
-+ bool d0_lpt_enable;
-+ struct bw_fixed d0_htotal;
-+ struct bw_fixed d0_pixel_rate;
-+ struct bw_fixed d0_graphics_src_width;
-+ struct bw_fixed d0_graphics_src_height;
-+ struct bw_fixed d0_graphics_scale_ratio;
-+ enum bw_stereo_mode d0_graphics_stereo_mode;
-+ enum bw_ul_mode d0_underlay_mode;
-+ struct bw_fixed d0_underlay_scale_ratio;
-+ struct bw_fixed d1_htotal;
-+ struct bw_fixed d1_pixel_rate;
-+ struct bw_fixed d1_graphics_src_width;
-+ struct bw_fixed d1_graphics_src_height;
-+ struct bw_fixed d1_graphics_scale_ratio;
-+ enum bw_stereo_mode d1_graphics_stereo_mode;
-+ bool d1_display_write_back_dwb_enable;
-+ enum bw_ul_mode d1_underlay_mode;
-+ struct bw_fixed d1_underlay_scale_ratio;
-+ struct bw_fixed d2_htotal;
-+ struct bw_fixed d2_pixel_rate;
-+ struct bw_fixed d2_graphics_src_width;
-+ struct bw_fixed d2_graphics_src_height;
-+ struct bw_fixed d2_graphics_scale_ratio;
-+ enum bw_stereo_mode d2_graphics_stereo_mode;
-+};
-+
-+struct bw_calcs_input_single_display {
-+ uint32_t graphics_rotation_angle;
-+ uint32_t underlay_rotation_angle;
-+ enum bw_underlay_surface_type underlay_surface_type;
-+ enum bw_panning_and_bezel_adj panning_and_bezel_adjustment;
-+ uint32_t graphics_bytes_per_pixel;
-+ bool graphics_interlace_mode;
-+ enum bw_tiling_mode graphics_tiling_mode;
-+ uint32_t graphics_h_taps;
-+ uint32_t graphics_v_taps;
-+ uint32_t graphics_lb_bpc;
-+ uint32_t underlay_lb_bpc;
-+ enum bw_tiling_mode underlay_tiling_mode;
-+ uint32_t underlay_h_taps;
-+ uint32_t underlay_v_taps;
-+ uint32_t underlay_src_width;
-+ uint32_t underlay_src_height;
-+ uint32_t underlay_pitch_in_pixels;
-+ enum bw_stereo_mode underlay_stereo_mode;
-+ bool fbc_enable;
-+ bool lpt_enable;
-+ uint32_t h_total;
-+ struct bw_fixed pixel_rate;
-+ uint32_t graphics_src_width;
-+ uint32_t graphics_src_height;
-+ struct bw_fixed graphics_scale_ratio;
-+ enum bw_stereo_mode graphics_stereo_mode;
-+ enum bw_ul_mode underlay_mode;
-+};
-+
-+#define BW_CALCS_MAX_NUM_DISPLAYS 3
-+
-+struct bw_calcs_input_mode_data {
-+ /* data for all displays */
-+ uint8_t number_of_displays;
-+ bool display_synchronization_enabled;
-+
-+ struct bw_calcs_input_single_display
-+ displays_data[BW_CALCS_MAX_NUM_DISPLAYS];
-+};
-+
-+/*******************************************************************************
-+ * Output data structure(s).
-+ ******************************************************************************/
-+#define maximum_number_of_surfaces 12
-+struct bw_results_internal {
-+ bool cpup_state_change_enable;
-+ bool cpuc_state_change_enable;
-+ bool nbp_state_change_enable;
-+ bool stutter_mode_enable;
-+ struct bw_fixed number_of_underlay_surfaces;
-+ struct bw_fixed src_width_after_surface_type;
-+ struct bw_fixed src_height_after_surface_type;
-+ struct bw_fixed hsr_after_surface_type;
-+ struct bw_fixed vsr_after_surface_type;
-+ struct bw_fixed src_width_after_rotation;
-+ struct bw_fixed src_height_after_rotation;
-+ struct bw_fixed hsr_after_rotation;
-+ struct bw_fixed vsr_after_rotation;
-+ struct bw_fixed source_height_pixels;
-+ struct bw_fixed hsr_after_stereo;
-+ struct bw_fixed vsr_after_stereo;
-+ struct bw_fixed source_width_in_lb;
-+ struct bw_fixed lb_line_pitch;
-+ struct bw_fixed underlay_maximum_source_efficient_for_tiling;
-+ struct bw_fixed num_lines_at_frame_start;
-+ struct bw_fixed min_dmif_size_in_time;
-+ struct bw_fixed min_mcifwr_size_in_time;
-+ struct bw_fixed total_requests_for_dmif_size;
-+ struct bw_fixed peak_pte_request_to_eviction_ratio_limiting;
-+ struct bw_fixed useful_pte_per_pte_request;
-+ struct bw_fixed scatter_gather_pte_request_rows;
-+ struct bw_fixed scatter_gather_row_height;
-+ struct bw_fixed scatter_gather_pte_requests_in_vblank;
-+ struct bw_fixed inefficient_linear_pitch_in_bytes;
-+ struct bw_fixed inefficient_underlay_pitch_in_pixels;
-+ struct bw_fixed minimum_underlay_pitch_padding_recommended_for_efficiency;
-+ struct bw_fixed cursor_total_data;
-+ struct bw_fixed cursor_total_request_groups;
-+ struct bw_fixed scatter_gather_total_pte_requests;
-+ struct bw_fixed scatter_gather_total_pte_request_groups;
-+ struct bw_fixed tile_width_in_pixels;
-+ struct bw_fixed dmif_total_number_of_data_request_page_close_open;
-+ struct bw_fixed mcifwr_total_number_of_data_request_page_close_open;
-+ struct bw_fixed bytes_per_page_close_open;
-+ struct bw_fixed mcifwr_total_page_close_open_time;
-+ struct bw_fixed total_requests_for_adjusted_dmif_size;
-+ struct bw_fixed total_dmifmc_urgent_trips;
-+ struct bw_fixed total_dmifmc_urgent_latency;
-+ struct bw_fixed total_display_reads_required_data;
-+ struct bw_fixed total_display_reads_required_dram_access_data;
-+ struct bw_fixed total_display_writes_required_data;
-+ struct bw_fixed total_display_writes_required_dram_access_data;
-+ struct bw_fixed display_reads_required_data;
-+ struct bw_fixed display_reads_required_dram_access_data;
-+ struct bw_fixed dmif_total_page_close_open_time;
-+ struct bw_fixed min_cursor_memory_interface_buffer_size_in_time;
-+ struct bw_fixed min_read_buffer_size_in_time;
-+ struct bw_fixed display_reads_time_for_data_transfer;
-+ struct bw_fixed display_writes_time_for_data_transfer;
-+ struct bw_fixed dmif_required_dram_bandwidth;
-+ struct bw_fixed mcifwr_required_dram_bandwidth;
-+ struct bw_fixed required_dmifmc_urgent_latency_for_page_close_open;
-+ struct bw_fixed required_mcifmcwr_urgent_latency;
-+ struct bw_fixed required_dram_bandwidth_gbyte_per_second;
-+ struct bw_fixed dram_bandwidth;
-+ struct bw_fixed dmif_required_sclk;
-+ struct bw_fixed mcifwr_required_sclk;
-+ struct bw_fixed required_sclk;
-+ struct bw_fixed downspread_factor;
-+ struct bw_fixed v_scaler_efficiency;
-+ struct bw_fixed scaler_limits_factor;
-+ struct bw_fixed display_pipe_pixel_throughput;
-+ struct bw_fixed total_dispclk_required_with_ramping;
-+ struct bw_fixed total_dispclk_required_without_ramping;
-+ struct bw_fixed total_read_request_bandwidth;
-+ struct bw_fixed total_write_request_bandwidth;
-+ struct bw_fixed dispclk_required_for_total_read_request_bandwidth;
-+ struct bw_fixed total_dispclk_required_with_ramping_with_request_bandwidth;
-+ struct bw_fixed total_dispclk_required_without_ramping_with_request_bandwidth;
-+ struct bw_fixed dispclk;
-+ struct bw_fixed blackout_recovery_time;
-+ struct bw_fixed min_pixels_per_data_fifo_entry;
-+ struct bw_fixed sclk_deep_sleep;
-+ struct bw_fixed chunk_request_time;
-+ struct bw_fixed cursor_request_time;
-+ struct bw_fixed line_source_pixels_transfer_time;
-+ struct bw_fixed dmifdram_access_efficiency;
-+ struct bw_fixed mcifwrdram_access_efficiency;
-+ struct bw_fixed total_average_bandwidth_no_compression;
-+ struct bw_fixed total_average_bandwidth;
-+ struct bw_fixed total_stutter_cycle_duration;
-+ struct bw_fixed stutter_burst_time;
-+ struct bw_fixed time_in_self_refresh;
-+ struct bw_fixed stutter_efficiency;
-+ struct bw_fixed worst_number_of_trips_to_memory;
-+ struct bw_fixed immediate_flip_time;
-+ struct bw_fixed latency_for_non_dmif_clients;
-+ struct bw_fixed latency_for_non_mcifwr_clients;
-+ struct bw_fixed dmifmc_urgent_latency_supported_in_high_sclk_and_yclk;
-+ struct bw_fixed nbp_state_dram_speed_change_margin;
-+ struct bw_fixed display_reads_time_for_data_transfer_and_urgent_latency;
-+ bool use_alpha[maximum_number_of_surfaces];
-+ bool orthogonal_rotation[maximum_number_of_surfaces];
-+ bool enable[maximum_number_of_surfaces];
-+ bool access_one_channel_only[maximum_number_of_surfaces];
-+ bool scatter_gather_enable_for_pipe[maximum_number_of_surfaces];
-+ bool interlace_mode[maximum_number_of_surfaces];
-+ struct bw_fixed bytes_per_pixel[maximum_number_of_surfaces];
-+ struct bw_fixed h_total[maximum_number_of_surfaces];
-+ struct bw_fixed pixel_rate[maximum_number_of_surfaces];
-+ struct bw_fixed src_width[maximum_number_of_surfaces];
-+ struct bw_fixed pitch_in_pixels[maximum_number_of_surfaces];
-+ struct bw_fixed pitch_in_pixels_after_surface_type[maximum_number_of_surfaces];
-+ struct bw_fixed src_height[maximum_number_of_surfaces];
-+ struct bw_fixed scale_ratio[maximum_number_of_surfaces];
-+ struct bw_fixed h_taps[maximum_number_of_surfaces];
-+ struct bw_fixed v_taps[maximum_number_of_surfaces];
-+ struct bw_fixed rotation_angle[maximum_number_of_surfaces];
-+ struct bw_fixed lb_bpc[maximum_number_of_surfaces];
-+ struct bw_fixed compression_rate[maximum_number_of_surfaces];
-+ struct bw_fixed hsr[maximum_number_of_surfaces];
-+ struct bw_fixed vsr[maximum_number_of_surfaces];
-+ struct bw_fixed source_width_rounded_up_to_chunks[maximum_number_of_surfaces];
-+ struct bw_fixed source_width_pixels[maximum_number_of_surfaces];
-+ struct bw_fixed source_height_rounded_up_to_chunks[maximum_number_of_surfaces];
-+ struct bw_fixed display_bandwidth[maximum_number_of_surfaces];
-+ struct bw_fixed request_bandwidth[maximum_number_of_surfaces];
-+ struct bw_fixed bytes_per_request[maximum_number_of_surfaces];
-+ struct bw_fixed useful_bytes_per_request[maximum_number_of_surfaces];
-+ struct bw_fixed lines_interleaved_in_mem_access[maximum_number_of_surfaces];
-+ struct bw_fixed latency_hiding_lines[maximum_number_of_surfaces];
-+ struct bw_fixed lb_partitions[maximum_number_of_surfaces];
-+ struct bw_fixed lb_partitions_max[maximum_number_of_surfaces];
-+ struct bw_fixed dispclk_required_with_ramping[maximum_number_of_surfaces];
-+ struct bw_fixed dispclk_required_without_ramping[maximum_number_of_surfaces];
-+ struct bw_fixed data_buffer_size[maximum_number_of_surfaces];
-+ struct bw_fixed outstanding_chunk_request_limit[maximum_number_of_surfaces];
-+ struct bw_fixed urgent_watermark[maximum_number_of_surfaces];
-+ struct bw_fixed stutter_exit_watermark[maximum_number_of_surfaces];
-+ struct bw_fixed nbp_state_change_watermark[maximum_number_of_surfaces];
-+ struct bw_fixed v_filter_init[maximum_number_of_surfaces];
-+ struct bw_fixed stutter_cycle_duration[maximum_number_of_surfaces];
-+ struct bw_fixed average_bandwidth[maximum_number_of_surfaces];
-+ struct bw_fixed average_bandwidth_no_compression[maximum_number_of_surfaces];
-+ struct bw_fixed scatter_gather_pte_request_limit[maximum_number_of_surfaces];
-+ struct bw_fixed lb_size_per_component[maximum_number_of_surfaces];
-+ struct bw_fixed memory_chunk_size_in_bytes[maximum_number_of_surfaces];
-+ struct bw_fixed pipe_chunk_size_in_bytes[maximum_number_of_surfaces];
-+ struct bw_fixed number_of_trips_to_memory_for_getting_apte_row[maximum_number_of_surfaces];
-+ struct bw_fixed adjusted_data_buffer_size[maximum_number_of_surfaces];
-+ struct bw_fixed adjusted_data_buffer_size_in_memory[maximum_number_of_surfaces];
-+ struct bw_fixed pixels_per_data_fifo_entry[maximum_number_of_surfaces];
-+ struct bw_fixed scatter_gather_pte_requests_in_row[maximum_number_of_surfaces];
-+ struct bw_fixed pte_request_per_chunk[maximum_number_of_surfaces];
-+ struct bw_fixed scatter_gather_page_width[maximum_number_of_surfaces];
-+ struct bw_fixed scatter_gather_page_height[maximum_number_of_surfaces];
-+ struct bw_fixed lb_lines_in_per_line_out_in_beginning_of_frame[maximum_number_of_surfaces];
-+ struct bw_fixed lb_lines_in_per_line_out_in_middle_of_frame[maximum_number_of_surfaces];
-+ struct bw_fixed cursor_width_pixels[maximum_number_of_surfaces];
-+ struct bw_fixed line_buffer_prefetch[maximum_number_of_surfaces];
-+ struct bw_fixed minimum_latency_hiding[maximum_number_of_surfaces];
-+ struct bw_fixed maximum_latency_hiding[maximum_number_of_surfaces];
-+ struct bw_fixed minimum_latency_hiding_with_cursor[maximum_number_of_surfaces];
-+ struct bw_fixed maximum_latency_hiding_with_cursor[maximum_number_of_surfaces];
-+ struct bw_fixed src_pixels_for_first_output_pixel[maximum_number_of_surfaces];
-+ struct bw_fixed src_pixels_for_last_output_pixel[maximum_number_of_surfaces];
-+ struct bw_fixed src_data_for_first_output_pixel[maximum_number_of_surfaces];
-+ struct bw_fixed src_data_for_last_output_pixel[maximum_number_of_surfaces];
-+ struct bw_fixed active_time[maximum_number_of_surfaces];
-+ struct bw_fixed horizontal_blank_and_chunk_granularity_factor[maximum_number_of_surfaces];
-+ struct bw_fixed cursor_latency_hiding[maximum_number_of_surfaces];
-+ struct bw_fixed dmif_burst_time[3][3];
-+ struct bw_fixed mcifwr_burst_time[3][3];
-+ struct bw_fixed line_source_transfer_time[maximum_number_of_surfaces][3][3];
-+ struct bw_fixed dram_speed_change_margin[3][3];
-+ struct bw_fixed dispclk_required_for_dram_speed_change[3][3];
-+ struct bw_fixed blackout_duration_margin[3][3];
-+ struct bw_fixed dispclk_required_for_blackout_duration[3][3];
-+ struct bw_fixed dispclk_required_for_blackout_recovery[3][3];
-+ struct bw_fixed dmif_required_sclk_for_urgent_latency[6];
-+};
-+
-+struct bw_watermarks {
-+ uint32_t a_mark;
-+ uint32_t b_mark;
-+};
-+
-+struct bw_calcs_output {
-+ bool cpuc_state_change_enable;
-+ bool cpup_state_change_enable;
-+ bool stutter_mode_enable;
-+ bool nbp_state_change_enable;
-+ struct bw_watermarks urgent_watermark[4];
-+ struct bw_watermarks stutter_exit_watermark[4];
-+ struct bw_watermarks nbp_state_change_watermark[4];
-+ uint32_t required_sclk;
-+ uint32_t dispclk;
-+};
-+
-+
-+/**
-+ * Initialize structures with data which will NOT change at runtime.
-+ */
-+void bw_calcs_init(
-+ struct bw_calcs_input_dceip *bw_dceip,
-+ struct bw_calcs_input_vbios *bw_vbios);
-+
-+/**
-+ * Return:
-+ * true - Display(s) configuration supported.
-+ * In this case 'calcs_output' contains data for HW programming
-+ * false - Display(s) configuration not supported (not enough bandwidth).
-+ */
-+bool bw_calcs(
-+ struct dc_context *ctx,
-+ const struct bw_calcs_input_dceip *dceip,
-+ const struct bw_calcs_input_vbios *vbios,
-+ const struct bw_calcs_input_mode_data *mode_data,
-+ struct bw_calcs_output *calcs_output);
-+
-+
-+#endif /* __BANDWIDTH_CALCS_H__ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/bw_fixed.h b/drivers/gpu/drm/amd/dal/dc/inc/bw_fixed.h
-new file mode 100644
-index 0000000..f9e267b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/bw_fixed.h
-@@ -0,0 +1,60 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef BW_FIXED_H_
-+#define BW_FIXED_H_
-+
-+struct bw_fixed {
-+ signed long long value;
-+};
-+
-+struct bw_fixed bw_min3(struct bw_fixed v1, struct bw_fixed v2, struct bw_fixed v3);
-+
-+struct bw_fixed bw_max3(struct bw_fixed v1, struct bw_fixed v2, struct bw_fixed v3);
-+
-+struct bw_fixed int_to_fixed(long long value);
-+
-+struct bw_fixed frc_to_fixed(long long num, long long denum);
-+
-+struct bw_fixed fixed31_32_to_bw_fixed(long long raw);
-+
-+struct bw_fixed add(const struct bw_fixed arg1, const struct bw_fixed arg2);
-+struct bw_fixed sub(const struct bw_fixed arg1, const struct bw_fixed arg2);
-+struct bw_fixed mul(const struct bw_fixed arg1, const struct bw_fixed arg2);
-+struct bw_fixed bw_div(const struct bw_fixed arg1, const struct bw_fixed arg2);
-+
-+struct bw_fixed bw_min(const struct bw_fixed arg1, const struct bw_fixed arg2);
-+struct bw_fixed bw_max(const struct bw_fixed arg1, const struct bw_fixed arg2);
-+struct bw_fixed bw_floor(const struct bw_fixed arg, const struct bw_fixed significance);
-+struct bw_fixed bw_ceil(const struct bw_fixed arg, const struct bw_fixed significance);
-+
-+bool equ(const struct bw_fixed arg1, const struct bw_fixed arg2);
-+bool neq(const struct bw_fixed arg1, const struct bw_fixed arg2);
-+bool leq(const struct bw_fixed arg1, const struct bw_fixed arg2);
-+bool geq(const struct bw_fixed arg1, const struct bw_fixed arg2);
-+bool ltn(const struct bw_fixed arg1, const struct bw_fixed arg2);
-+bool gtn(const struct bw_fixed arg1, const struct bw_fixed arg2);
-+
-+#endif //BW_FIXED_H_
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/compressor.h b/drivers/gpu/drm/amd/dal/dc/inc/compressor.h
-new file mode 100644
-index 0000000..4992ffd
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/compressor.h
-@@ -0,0 +1,140 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_COMPRESSOR_H__
-+#define __DAL_COMPRESSOR_H__
-+
-+#include "include/grph_object_id.h"
-+
-+enum fbc_compress_ratio {
-+ FBC_COMPRESS_RATIO_INVALID = 0,
-+ FBC_COMPRESS_RATIO_1TO1 = 1,
-+ FBC_COMPRESS_RATIO_2TO1 = 2,
-+ FBC_COMPRESS_RATIO_4TO1 = 4,
-+ FBC_COMPRESS_RATIO_8TO1 = 8,
-+};
-+
-+union fbc_physical_address {
-+ struct {
-+ uint32_t low_part;
-+ int32_t high_part;
-+ } addr;
-+};
-+
-+struct compr_addr_and_pitch_params {
-+ uint32_t inst;
-+ uint32_t source_view_width;
-+ uint32_t source_view_height;
-+};
-+
-+struct fbc_lpt_config {
-+ uint32_t mem_channels_num;
-+ uint32_t banks_num;
-+ uint32_t chan_interleave_size;
-+ uint32_t row_size;
-+};
-+
-+struct fbc_input_info {
-+ bool dynamic_fbc_buffer_alloc;
-+ uint32_t source_view_width;
-+ uint32_t source_view_height;
-+ uint32_t active_targets_num;
-+ struct fbc_lpt_config lpt_config;
-+};
-+
-+struct fbc_requested_compressed_size {
-+ uint32_t preferred_size;
-+ uint32_t preferred_size_alignment;
-+ uint32_t min_size;
-+ uint32_t min_size_alignment;
-+ union {
-+ struct {
-+ /*Above preferred_size must be allocated in FB pool */
-+ uint32_t PREFERRED_MUST_BE_FRAME_BUFFER_POOL:1;
-+ /*Above min_size must be allocated in FB pool */
-+ uint32_t MIN_MUST_BE_FRAME_BUFFER_POOL:1;
-+ } flags;
-+ uint32_t bits;
-+ };
-+};
-+
-+struct fbc_compressed_surface_info {
-+ union fbc_physical_address compressed_surface_address;
-+ uint32_t allocated_size;
-+ union {
-+ struct {
-+ uint32_t FB_POOL:1; /*Allocated in FB Pool */
-+ uint32_t DYNAMIC_ALLOC:1; /*Dynamic allocation */
-+ } allocation_flags;
-+ uint32_t bits;
-+ };
-+};
-+
-+enum fbc_hw_max_resolution_supported {
-+ FBC_MAX_X = 3840,
-+ FBC_MAX_Y = 2400
-+};
-+
-+struct fbc_max_resolution_supported {
-+ uint32_t source_view_width;
-+ uint32_t source_view_height;
-+};
-+
-+struct compressor {
-+ struct dc_context *ctx;
-+ uint32_t attached_inst;
-+ bool is_enabled;
-+
-+ union {
-+ uint32_t raw;
-+ struct {
-+ uint32_t FBC_SUPPORT:1;
-+ uint32_t FB_POOL:1;
-+ uint32_t DYNAMIC_ALLOC:1;
-+ uint32_t LPT_SUPPORT:1;
-+ uint32_t LPT_MC_CONFIG:1;
-+ uint32_t DUMMY_BACKEND:1;
-+ uint32_t CLK_GATING_DISABLED:1;
-+
-+ } bits;
-+ } options;
-+
-+ union fbc_physical_address compr_surface_address;
-+
-+ uint32_t embedded_panel_h_size;
-+ uint32_t embedded_panel_v_size;
-+ uint32_t memory_bus_width;
-+ uint32_t banks_num;
-+ uint32_t raw_size;
-+ uint32_t channel_interleave_size;
-+ uint32_t dram_channels_num;
-+
-+ uint32_t allocated_size;
-+ uint32_t preferred_requested_size;
-+ uint32_t lpt_channels_num;
-+ enum fbc_compress_ratio min_compress_ratio;
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/core_dc.h b/drivers/gpu/drm/amd/dal/dc/inc/core_dc.h
-new file mode 100644
-index 0000000..dc246e8
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/core_dc.h
-@@ -0,0 +1,39 @@
-+/*
-+ * core_dc.h
-+ *
-+ * Created on: Nov 13, 2015
-+ * Author: yonsun
-+ */
-+
-+#ifndef __CORE_DC_H__
-+#define __CORE_DC_H__
-+
-+#include "core_types.h"
-+#include "hw_sequencer.h"
-+
-+
-+struct dc {
-+ struct dc_context *ctx;
-+
-+ /** link-related data - begin **/
-+ uint8_t link_count;
-+ struct core_link **links;
-+ /** link-related data - end **/
-+
-+ /* TODO: determine max number of targets*/
-+ struct validate_context current_context;
-+ struct resource_pool res_pool;
-+
-+ /*Power State*/
-+ enum dc_video_power_state previous_power_state;
-+ enum dc_video_power_state current_power_state;
-+
-+ /* Inputs into BW and WM calculations. */
-+ struct bw_calcs_input_dceip bw_dceip;
-+ struct bw_calcs_input_vbios bw_vbios;
-+
-+ /* HW functions */
-+ struct hw_sequencer_funcs hwss;
-+};
-+
-+#endif /* __CORE_DC_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/core_status.h b/drivers/gpu/drm/amd/dal/dc/inc/core_status.h
-new file mode 100644
-index 0000000..9682cf8
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/core_status.h
-@@ -0,0 +1,46 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef _CORE_STATUS_H_
-+#define _CORE_STATUS_H_
-+
-+enum dc_status {
-+ DC_OK = 1,
-+
-+ DC_NO_CONTROLLER_RESOURCE,
-+ DC_NO_STREAM_ENG_RESOURCE,
-+ DC_NO_STREAM_AUDIO_RESOURCE,
-+ DC_NO_CLOCK_SOURCE_RESOURCE,
-+ DC_FAIL_CONTROLLER_VALIDATE,
-+ DC_FAIL_ENC_VALIDATE,
-+ DC_FAIL_ATTACH_SURFACES,
-+ DC_NO_DP_LINK_BANDWIDTH,
-+ DC_EXCEED_DONGLE_MAX_CLK,
-+ DC_FAIL_BANDWIDTH_VALIDATE, /* BW and Watermark validation */
-+
-+ DC_ERROR_UNEXPECTED = -1
-+};
-+
-+#endif /* _CORE_STATUS_H_ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/core_types.h b/drivers/gpu/drm/amd/dal/dc/inc/core_types.h
-new file mode 100644
-index 0000000..22ab6cb
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/core_types.h
-@@ -0,0 +1,308 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef _CORE_TYPES_H_
-+#define _CORE_TYPES_H_
-+
-+#include "dc.h"
-+#include "bandwidth_calcs.h"
-+#include "ddc_service_types.h"
-+
-+struct core_stream;
-+/********* core_target *************/
-+
-+#define CONST_DC_TARGET_TO_CORE(dc_target) \
-+ container_of(dc_target, const struct core_target, public)
-+#define DC_TARGET_TO_CORE(dc_target) \
-+ container_of(dc_target, struct core_target, public)
-+
-+#define MAX_PIPES 6
-+#define MAX_STREAMS 6
-+#define MAX_CLOCK_SOURCES 4
-+
-+struct core_target {
-+ struct dc_target public;
-+ struct dc_target_status status;
-+
-+ struct core_stream *streams[MAX_STREAMS];
-+ uint8_t stream_count;
-+ struct dc_context *ctx;
-+};
-+
-+/********* core_surface **********/
-+#define DC_SURFACE_TO_CORE(dc_surface) \
-+ container_of(dc_surface, struct core_surface, public)
-+
-+struct core_surface {
-+ struct dc_surface public;
-+ struct dc_surface_status status;
-+ struct dc_context *ctx;
-+};
-+
-+void enable_surface_flip_reporting(struct dc_surface *dc_surface,
-+ uint32_t controller_id);
-+
-+/********* core_stream ************/
-+#include "grph_object_id.h"
-+#include "encoder_interface.h"
-+#include "clock_source_interface.h"
-+#include "audio_interface.h"
-+
-+#define DC_STREAM_TO_CORE(dc_stream) container_of( \
-+ dc_stream, struct core_stream, public)
-+
-+#define PIXEL_CLOCK 27030
-+
-+struct core_stream {
-+ struct dc_stream public;
-+
-+ /* field internal to DC */
-+ const struct core_sink *sink;
-+
-+ struct clock_source *clock_source;
-+
-+ struct mem_input *mi;
-+ struct input_pixel_processor *ipp;
-+ struct transform *xfm;
-+ struct output_pixel_processor *opp;
-+ struct timing_generator *tg;
-+ struct stream_encoder *stream_enc;
-+ struct display_clock *dis_clk;
-+
-+ struct overscan_info overscan;
-+ struct scaling_ratios ratios;
-+ struct rect viewport;
-+ struct scaling_taps taps;
-+ enum pixel_format format;
-+
-+ uint8_t controller_idx;
-+
-+ struct audio *audio;
-+
-+ enum signal_type signal;
-+
-+ /* TODO: move these members into appropriate places (work in progress)*/
-+ /* timing validation (HDMI only) */
-+ uint32_t max_tmds_clk_from_edid_in_mhz;
-+ /* maximum supported deep color depth for HDMI */
-+ enum dc_color_depth max_hdmi_deep_color;
-+ /* maximum supported pixel clock for HDMI */
-+ uint32_t max_hdmi_pixel_clock;
-+ /* end of TODO */
-+
-+ /*TODO: AUTO merge if possible*/
-+ struct pixel_clk_params pix_clk_params;
-+ struct pll_settings pll_settings;
-+
-+ /*fmt*/
-+ /*TODO: AUTO new codepath in apply_context to hw to
-+ * generate these bw unrelated/no fail params*/
-+ struct bit_depth_reduction_params fmt_bit_depth;
-+ struct clamping_and_pixel_encoding_params clamping;
-+ struct hw_info_frame info_frame;
-+ struct encoder_info_frame encoder_info_frame;
-+
-+ struct audio_output audio_output;
-+ struct dc_context *ctx;
-+};
-+
-+
-+/************ core_sink *****************/
-+
-+#define DC_SINK_TO_CORE(dc_sink) \
-+ container_of(dc_sink, struct core_sink, public)
-+
-+struct core_sink {
-+ /** The public, read-only (for DM) area of sink. **/
-+ struct dc_sink public;
-+ /** End-of-public area. **/
-+
-+ /** The 'protected' area - read/write access, for use only inside DC **/
-+ /* not used for now */
-+ struct core_link *link;
-+ struct dc_context *ctx;
-+ uint32_t dongle_max_pix_clk;
-+ bool converter_disable_audio;
-+};
-+
-+/************ link *****************/
-+#define DC_LINK_TO_CORE(dc_link) container_of(dc_link, struct core_link, public)
-+
-+struct link_init_data {
-+ const struct dc *dc;
-+ struct dc_context *ctx; /* TODO: remove 'dal' when DC is complete. */
-+ uint32_t connector_index; /* this will be mapped to the HPD pins */
-+ uint32_t link_index; /* this is mapped to DAL display_index
-+ TODO: remove it when DC is complete. */
-+ struct adapter_service *adapter_srv;
-+};
-+
-+struct link_caps {
-+ /* support for Spread Spectrum(SS) */
-+ bool ss_supported;
-+ /* DP link settings (laneCount, linkRate, Spread) */
-+ uint32_t lane_count;
-+ uint32_t rate;
-+ uint32_t spread;
-+ enum dpcd_revision dpcd_revision;
-+};
-+
-+struct dpcd_caps {
-+ union dpcd_rev dpcd_rev;
-+ union max_lane_count max_ln_count;
-+
-+ /* dongle type (DP converter, CV smart dongle) */
-+ enum display_dongle_type dongle_type;
-+ /* Dongle's downstream count. */
-+ union sink_count sink_count;
-+ /* If dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER,
-+ indicates 'Frame Sequential-to-lllFrame Pack' conversion capability.*/
-+ bool is_dp_hdmi_s3d_converter;
-+
-+ bool allow_invalid_MSA_timing_param;
-+ bool panel_mode_edp;
-+ uint32_t sink_dev_id;
-+ uint32_t branch_dev_id;
-+ int8_t branch_dev_name[6];
-+};
-+
-+union dp_wa {
-+ struct {
-+ /* keep DP receiver powered up on DisplayOutput */
-+ uint32_t KEEP_RECEIVER_POWERED:1;
-+
-+ /* TODO: may add other member in.*/
-+ } bits;
-+ uint32_t raw;
-+};
-+
-+struct core_link {
-+ struct dc_link public;
-+ const struct dc *dc;
-+
-+ struct dc_context *ctx; /* TODO: AUTO remove 'dal' when DC is complete*/
-+
-+ uint8_t connector_index; /* this will be mapped to the HPD pins */
-+ uint8_t link_index; /* this is mapped to DAL display_index
-+ TODO: #flip remove it as soon as possible. */
-+
-+ struct adapter_service *adapter_srv;
-+ struct connector *connector;
-+ struct link_encoder *link_enc;
-+ struct ddc_service *ddc;
-+ struct graphics_object_id link_id;
-+ /* caps is the same as reported_link_cap. link_traing use
-+ * reported_link_cap. Will clean up. TODO */
-+ struct link_settings reported_link_cap;
-+ struct link_settings verified_link_cap;
-+ struct link_settings max_link_setting;
-+ struct link_settings cur_link_settings;
-+ struct lane_settings ln_setting;
-+ struct dpcd_caps dpcd_caps;
-+ unsigned int dpcd_sink_count;
-+
-+ enum edp_revision edp_revision;
-+ union dp_wa dp_wa;
-+};
-+
-+#define DC_LINK_TO_LINK(dc_link) container_of(dc_link, struct core_link, public)
-+
-+struct core_link *link_create(const struct link_init_data *init_params);
-+void link_destroy(struct core_link **link);
-+enum dc_status core_link_enable(struct core_stream *stream);
-+
-+enum dc_status core_link_disable(struct core_stream *stream);
-+
-+enum dc_status dc_link_validate_mode_timing(
-+ const struct core_sink *sink,
-+ struct core_link *link,
-+ const struct dc_crtc_timing *timing);
-+
-+void core_link_resume(struct core_link *link);
-+
-+/********** DAL Core*********************/
-+#include "display_clock_interface.h"
-+
-+struct resource_pool {
-+ struct scaler_filter * scaler_filter;
-+
-+ struct mem_input *mis[MAX_PIPES];
-+ struct input_pixel_processor *ipps[MAX_PIPES];
-+ struct transform *transforms[MAX_PIPES];
-+ struct output_pixel_processor *opps[MAX_PIPES];
-+ struct timing_generator *timing_generators[MAX_STREAMS];
-+ struct stream_encoder *stream_enc[MAX_STREAMS];
-+
-+ uint8_t controller_count;
-+ uint8_t stream_enc_count;
-+
-+ union supported_stream_engines stream_engines;
-+
-+ struct clock_source *clock_sources[MAX_CLOCK_SOURCES];
-+ uint8_t clk_src_count;
-+
-+ struct audio *audios[MAX_STREAMS];
-+ uint8_t audio_count;
-+
-+ struct display_clock *display_clock;
-+ struct adapter_service *adapter_srv;
-+ struct irq_service *irqs;
-+};
-+
-+struct controller_ctx {
-+ struct core_surface *surface;
-+ struct core_stream *stream;
-+ struct flags {
-+ bool unchanged;
-+ bool timing_changed;
-+ } flags;
-+};
-+
-+struct resource_context {
-+ struct resource_pool pool;
-+ struct controller_ctx controller_ctx[MAX_PIPES];
-+ union supported_stream_engines used_stream_engines;
-+ bool is_stream_enc_acquired[MAX_STREAMS];
-+ bool is_audio_acquired[MAX_STREAMS];
-+ uint8_t clock_source_ref_count[MAX_CLOCK_SOURCES];
-+ };
-+
-+struct target_flags {
-+ bool unchanged;
-+};
-+struct validate_context {
-+ struct core_target *targets[MAX_PIPES];
-+ struct target_flags target_flags[MAX_PIPES];
-+ uint8_t target_count;
-+
-+ struct resource_context res_ctx;
-+
-+ struct bw_calcs_input_mode_data bw_mode_data;
-+ /* The output from BW and WM calculations. */
-+ struct bw_calcs_output bw_results;
-+};
-+
-+
-+#endif /* _CORE_TYPES_H_ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/dal/dc/inc/dc_link_dp.h
-new file mode 100644
-index 0000000..e3e4778
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/dc_link_dp.h
-@@ -0,0 +1,51 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_LINK_DP_H__
-+#define __DC_LINK_DP_H__
-+
-+bool dp_hbr_verify_link_cap(
-+ struct core_link *link,
-+ struct link_settings *known_limit_link_setting);
-+
-+bool dp_validate_mode_timing(
-+ struct core_link *link,
-+ const struct dc_crtc_timing *timing);
-+
-+void decide_link_settings(
-+ struct core_stream *stream,
-+ struct link_settings *link_setting);
-+
-+bool perform_link_training(
-+ struct core_link *link,
-+ const struct link_settings *link_setting,
-+ bool skip_video_pattern);
-+
-+/*dp mst functions*/
-+bool is_mst_supported(struct core_link *link);
-+
-+void detect_dp_sink_caps(struct core_link *link);
-+
-+#endif /* __DC_LINK_DP_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h
-new file mode 100644
-index 0000000..2c5738f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/hw_sequencer.h
-@@ -0,0 +1,170 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_HW_SEQUENCER_H__
-+#define __DC_HW_SEQUENCER_H__
-+#include "core_types.h"
-+
-+struct hw_sequencer_funcs {
-+
-+ enum dc_status (*apply_ctx_to_hw)(
-+ const struct dc *dc,
-+ struct validate_context *context);
-+
-+ void (*reset_hw_ctx)(struct dc *dc,
-+ struct validate_context *context,
-+ uint8_t target_count);
-+
-+ bool (*set_plane_config)(
-+ struct core_surface *surface,
-+ struct core_target *target);
-+
-+ bool (*update_plane_address)(
-+ const struct core_surface *surface,
-+ struct core_target *target);
-+
-+ bool (*enable_memory_requests)(struct timing_generator *tg);
-+
-+ bool (*disable_memory_requests)(struct timing_generator *tg);
-+
-+ bool (*transform_power_up)(struct transform *xfm);
-+
-+ bool (*cursor_set_attributes)(
-+ struct input_pixel_processor *ipp,
-+ const struct dc_cursor_attributes *attributes);
-+
-+ bool (*cursor_set_position)(
-+ struct input_pixel_processor *ipp,
-+ const struct dc_cursor_position *position);
-+
-+ bool (*set_gamma_ramp)(
-+ struct input_pixel_processor *ipp,
-+ struct output_pixel_processor *opp,
-+ const struct gamma_ramp *ramp,
-+ const struct gamma_parameters *params);
-+
-+ void (*power_down)(struct validate_context *context);
-+
-+ void (*enable_accelerated_mode)(struct validate_context *context);
-+
-+ void (*get_crtc_positions)(
-+ struct timing_generator *tg,
-+ int32_t *h_position,
-+ int32_t *v_position);
-+
-+ uint32_t (*get_vblank_counter)(struct timing_generator *tg);
-+
-+ void (*enable_timing_synchronization)(
-+ struct dc_context *dc_ctx,
-+ uint32_t timing_generator_num,
-+ struct timing_generator *tgs[]);
-+
-+ void (*disable_vga)(struct timing_generator *tg);
-+
-+
-+
-+ /* link encoder sequences */
-+ struct link_encoder *(*encoder_create)(const struct encoder_init_data *init);
-+
-+ void (*encoder_destroy)(struct link_encoder **enc);
-+
-+ enum encoder_result (*encoder_power_up)(
-+ struct link_encoder *enc);
-+
-+ enum encoder_result (*encoder_enable_output)(
-+ struct link_encoder *enc,
-+ const struct link_settings *link_settings,
-+ enum engine_id engine,
-+ enum clock_source_id clock_source,
-+ enum signal_type signal,
-+ enum dc_color_depth color_depth,
-+ uint32_t pixel_clock);
-+
-+ enum encoder_result (*encoder_disable_output)(
-+ struct link_encoder *enc,
-+ enum signal_type signal);
-+
-+ void (*encoder_set_dp_phy_pattern)(
-+ struct link_encoder *enc,
-+ const struct encoder_set_dp_phy_pattern_param *param);
-+
-+ enum encoder_result (*encoder_dp_set_lane_settings)(
-+ struct link_encoder *enc,
-+ const struct link_training_settings *link_settings);
-+
-+ /* backlight control */
-+ void (*encoder_set_lcd_backlight_level)(struct link_encoder *enc,
-+ uint32_t level);
-+
-+
-+ /* power management */
-+ void (*clock_gating_power_up)(
-+ struct dc_context *ctx,
-+ bool enable);
-+
-+ void (*enable_display_pipe_clock_gating)(
-+ struct dc_context *ctx,
-+ bool clock_gating);
-+
-+ bool (*enable_display_power_gating)(
-+ struct dc_context *ctx,
-+ uint8_t controller_id,
-+ struct bios_parser *bp,
-+ enum pipe_gating_control power_gating);
-+
-+ void (*set_afmt_memory_power_state)(
-+ const struct dc_context *ctx,
-+ enum engine_id id,
-+ bool enable);
-+
-+ /* resource management and validation*/
-+ bool (*construct_resource_pool)(
-+ struct adapter_service *adapter_serv,
-+ struct dc *dc,
-+ struct resource_pool *pool);
-+
-+ void (*destruct_resource_pool)(struct resource_pool *pool);
-+
-+ enum dc_status (*validate_with_context)(
-+ const struct dc *dc,
-+ const struct dc_validation_set set[],
-+ uint8_t set_count,
-+ struct validate_context *context);
-+
-+ enum dc_status (*validate_bandwidth)(
-+ const struct dc *dc,
-+ struct validate_context *context);
-+ void (*program_bw)(
-+ struct dc *dc,
-+ struct validate_context *context);
-+
-+};
-+
-+bool dc_construct_hw_sequencer(
-+ struct adapter_service *adapter_serv,
-+ struct dc *dc);
-+
-+
-+#endif /* __DC_HW_SEQUENCER_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/ipp.h b/drivers/gpu/drm/amd/dal/dc/inc/ipp.h
-new file mode 100644
-index 0000000..602b4cb
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/ipp.h
-@@ -0,0 +1,66 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_IPP_H__
-+#define __DAL_IPP_H__
-+
-+#include "include/plane_types.h"
-+#include "include/grph_object_id.h"
-+#include "include/grph_csc_types.h"
-+#include "include/video_csc_types.h"
-+#include "include/hw_sequencer_types.h"
-+
-+
-+#define MAXTRIX_COEFFICIENTS_NUMBER 12
-+#define MAXTRIX_COEFFICIENTS_WRAP_NUMBER (MAXTRIX_COEFFICIENTS_NUMBER + 4)
-+#define MAX_OVL_MATRIX_COUNT 12
-+
-+/* IPP RELATED */
-+struct input_pixel_processor {
-+ struct dc_context *ctx;
-+ uint32_t inst;
-+};
-+
-+enum wide_gamut_degamma_mode {
-+ /* 00 - BITS1:0 Bypass */
-+ WIDE_GAMUT_DEGAMMA_MODE_GRAPHICS_BYPASS,
-+ /* 0x1 - PWL gamma ROM A */
-+ WIDE_GAMUT_DEGAMMA_MODE_GRAPHICS_PWL_ROM_A,
-+ /* 0x2 - PWL gamma ROM B */
-+ WIDE_GAMUT_DEGAMMA_MODE_GRAPHICS_PWL_ROM_B,
-+ /* 00 - BITS5:4 Bypass */
-+ WIDE_GAMUT_DEGAMMA_MODE_OVL_BYPASS,
-+ /* 0x1 - PWL gamma ROM A */
-+ WIDE_GAMUT_DEGAMMA_MODE_OVL_PWL_ROM_A,
-+ /* 0x2 - PWL gamma ROM B */
-+ WIDE_GAMUT_DEGAMMA_MODE_OVL_PWL_ROM_B,
-+};
-+
-+struct dcp_video_matrix {
-+ enum ovl_color_space color_space;
-+ int32_t value[MAXTRIX_COEFFICIENTS_NUMBER];
-+};
-+
-+#endif /* __DAL_IPP_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h b/drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h
-new file mode 100644
-index 0000000..7110357
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/link_hwss.h
-@@ -0,0 +1,67 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_LINK_HWSS_H__
-+#define __DC_LINK_HWSS_H__
-+
-+#include "inc/core_status.h"
-+
-+enum dc_status core_link_read_dpcd(
-+ struct core_link* link,
-+ uint32_t address,
-+ uint8_t *data,
-+ uint32_t size);
-+
-+enum dc_status core_link_write_dpcd(
-+ struct core_link* link,
-+ uint32_t address,
-+ const uint8_t *data,
-+ uint32_t size);
-+
-+enum dc_status dp_enable_link_phy(
-+ struct core_link *link,
-+ enum signal_type signal,
-+ enum engine_id engine,
-+ const struct link_settings *link_settings);
-+
-+void dp_receiver_power_ctrl(struct core_link *link, bool on);
-+
-+void dp_disable_link_phy(struct core_link *link, enum signal_type signal);
-+
-+bool dp_set_hw_training_pattern(
-+ struct core_link *link,
-+ enum hw_dp_training_pattern pattern);
-+
-+bool dp_set_hw_lane_settings(
-+ struct core_link *link,
-+ const struct link_training_settings *link_settings);
-+
-+void dp_set_hw_test_pattern(
-+ struct core_link *link,
-+ enum dp_test_pattern test_pattern);
-+
-+enum dp_panel_mode dp_get_panel_mode(struct core_link *link);
-+
-+#endif /* __DC_LINK_HWSS_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/mem_input.h b/drivers/gpu/drm/amd/dal/dc/inc/mem_input.h
-new file mode 100644
-index 0000000..458e7b5
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/mem_input.h
-@@ -0,0 +1,55 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef __DAL_MEM_INPUT_H__
-+#define __DAL_MEM_INPUT_H__
-+
-+#include "include/plane_types.h"
-+#include "include/grph_object_id.h"
-+#include "dc.h"
-+
-+struct mem_input {
-+ struct dc_context *ctx;
-+ uint32_t inst;
-+};
-+
-+enum stutter_mode_type {
-+ STUTTER_MODE_LEGACY = 0X00000001,
-+ STUTTER_MODE_ENHANCED = 0X00000002,
-+ STUTTER_MODE_FID_NBP_STATE = 0X00000004,
-+ STUTTER_MODE_WATERMARK_NBP_STATE = 0X00000008,
-+ STUTTER_MODE_SINGLE_DISPLAY_MODEL = 0X00000010,
-+ STUTTER_MODE_MIXED_DISPLAY_MODEL = 0X00000020,
-+ STUTTER_MODE_DUAL_DMIF_BUFFER = 0X00000040,
-+ STUTTER_MODE_NO_DMIF_BUFFER_ALLOCATION = 0X00000080,
-+ STUTTER_MODE_NO_ADVANCED_REQUEST = 0X00000100,
-+ STUTTER_MODE_NO_LB_RESET = 0X00000200,
-+ STUTTER_MODE_DISABLED = 0X00000400,
-+ STUTTER_MODE_AGGRESSIVE_MARKS = 0X00000800,
-+ STUTTER_MODE_URGENCY = 0X00001000,
-+ STUTTER_MODE_QUAD_DMIF_BUFFER = 0X00002000,
-+ STUTTER_MODE_NOT_USED = 0X00008000
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/opp.h b/drivers/gpu/drm/amd/dal/dc/inc/opp.h
-new file mode 100644
-index 0000000..3293e3b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/opp.h
-@@ -0,0 +1,206 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_OPP_H__
-+#define __DAL_OPP_H__
-+
-+#include "dc_temp.h"
-+#include "grph_object_id.h"
-+#include "grph_csc_types.h"
-+
-+struct fixed31_32;
-+
-+/* TODO: Need cleanup */
-+
-+enum wide_gamut_regamma_mode {
-+ /* 0x0 - BITS2:0 Bypass */
-+ WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_BYPASS,
-+ /* 0x1 - Fixed curve sRGB 2.4 */
-+ WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_SRGB24,
-+ /* 0x2 - Fixed curve xvYCC 2.22 */
-+ WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_XYYCC22,
-+ /* 0x3 - Programmable control A */
-+ WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_MATRIX_A,
-+ /* 0x4 - Programmable control B */
-+ WIDE_GAMUT_REGAMMA_MODE_GRAPHICS_MATRIX_B,
-+ /* 0x0 - BITS6:4 Bypass */
-+ WIDE_GAMUT_REGAMMA_MODE_OVL_BYPASS,
-+ /* 0x1 - Fixed curve sRGB 2.4 */
-+ WIDE_GAMUT_REGAMMA_MODE_OVL_SRGB24,
-+ /* 0x2 - Fixed curve xvYCC 2.22 */
-+ WIDE_GAMUT_REGAMMA_MODE_OVL_XYYCC22,
-+ /* 0x3 - Programmable control A */
-+ WIDE_GAMUT_REGAMMA_MODE_OVL_MATRIX_A,
-+ /* 0x4 - Programmable control B */
-+ WIDE_GAMUT_REGAMMA_MODE_OVL_MATRIX_B
-+};
-+
-+struct pwl_result_data {
-+ struct fixed31_32 red;
-+ struct fixed31_32 green;
-+ struct fixed31_32 blue;
-+
-+ struct fixed31_32 delta_red;
-+ struct fixed31_32 delta_green;
-+ struct fixed31_32 delta_blue;
-+
-+ uint32_t red_reg;
-+ uint32_t green_reg;
-+ uint32_t blue_reg;
-+
-+ uint32_t delta_red_reg;
-+ uint32_t delta_green_reg;
-+ uint32_t delta_blue_reg;
-+};
-+
-+struct gamma_pixel {
-+ struct fixed31_32 r;
-+ struct fixed31_32 g;
-+ struct fixed31_32 b;
-+};
-+
-+struct gamma_curve {
-+ uint32_t offset;
-+ uint32_t segments_num;
-+};
-+
-+struct curve_points {
-+ struct fixed31_32 x;
-+ struct fixed31_32 y;
-+ struct fixed31_32 offset;
-+ struct fixed31_32 slope;
-+
-+ uint32_t custom_float_x;
-+ uint32_t custom_float_y;
-+ uint32_t custom_float_offset;
-+ uint32_t custom_float_slope;
-+};
-+
-+enum channel_name {
-+ CHANNEL_NAME_RED,
-+ CHANNEL_NAME_GREEN,
-+ CHANNEL_NAME_BLUE
-+};
-+
-+struct custom_float_format {
-+ uint32_t mantissa_bits;
-+ uint32_t exponenta_bits;
-+ bool sign;
-+};
-+
-+struct custom_float_value {
-+ uint32_t mantissa;
-+ uint32_t exponenta;
-+ uint32_t value;
-+ bool negative;
-+};
-+
-+struct hw_x_point {
-+ uint32_t custom_float_x;
-+ uint32_t custom_float_x_adjusted;
-+ struct fixed31_32 x;
-+ struct fixed31_32 adjusted_x;
-+ struct fixed31_32 regamma_y_red;
-+ struct fixed31_32 regamma_y_green;
-+ struct fixed31_32 regamma_y_blue;
-+
-+};
-+
-+struct pwl_float_data_ex {
-+ struct fixed31_32 r;
-+ struct fixed31_32 g;
-+ struct fixed31_32 b;
-+ struct fixed31_32 delta_r;
-+ struct fixed31_32 delta_g;
-+ struct fixed31_32 delta_b;
-+};
-+
-+enum hw_point_position {
-+ /* hw point sits between left and right sw points */
-+ HW_POINT_POSITION_MIDDLE,
-+ /* hw point lays left from left (smaller) sw point */
-+ HW_POINT_POSITION_LEFT,
-+ /* hw point lays stays from right (bigger) sw point */
-+ HW_POINT_POSITION_RIGHT
-+};
-+
-+struct gamma_point {
-+ int32_t left_index;
-+ int32_t right_index;
-+ enum hw_point_position pos;
-+ struct fixed31_32 coeff;
-+};
-+
-+struct pixel_gamma_point {
-+ struct gamma_point r;
-+ struct gamma_point g;
-+ struct gamma_point b;
-+};
-+
-+struct gamma_coefficients {
-+ struct fixed31_32 a0[3];
-+ struct fixed31_32 a1[3];
-+ struct fixed31_32 a2[3];
-+ struct fixed31_32 a3[3];
-+ struct fixed31_32 user_gamma[3];
-+ struct fixed31_32 user_contrast;
-+ struct fixed31_32 user_brightness;
-+};
-+
-+struct csc_adjustments {
-+ struct fixed31_32 contrast;
-+ struct fixed31_32 saturation;
-+ struct fixed31_32 brightness;
-+ struct fixed31_32 hue;
-+};
-+
-+struct pwl_float_data {
-+ struct fixed31_32 r;
-+ struct fixed31_32 g;
-+ struct fixed31_32 b;
-+};
-+
-+
-+/* TODO: Use when we redefine the OPP interface */
-+enum opp_regamma {
-+ OPP_REGAMMA_BYPASS = 0,
-+ OPP_REGAMMA_SRGB,
-+ OPP_REGAMMA_3_6,
-+ OPP_REGAMMA_PQ,
-+ OPP_REGAMMA_PQ_INTERIM,
-+};
-+
-+struct output_pixel_processor {
-+ struct dc_context *ctx;
-+ uint32_t inst;
-+};
-+
-+enum fmt_stereo_action {
-+ FMT_STEREO_ACTION_ENABLE = 0,
-+ FMT_STEREO_ACTION_DISABLE,
-+ FMT_STEREO_ACTION_UPDATE_POLARITY
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/resource.h b/drivers/gpu/drm/amd/dal/dc/inc/resource.h
-new file mode 100644
-index 0000000..0e0ba47
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/resource.h
-@@ -0,0 +1,61 @@
-+/*
-+ * Copyright 2015 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ */
-+
-+#ifndef DRIVERS_GPU_DRM_AMD_DAL_DEV_DC_INC_RESOURCE_H_
-+#define DRIVERS_GPU_DRM_AMD_DAL_DEV_DC_INC_RESOURCE_H_
-+
-+#include "core_types.h"
-+#include "core_status.h"
-+#include "core_dc.h"
-+
-+void build_scaling_params(
-+ const struct dc_surface *surface,
-+ struct core_stream *stream);
-+
-+void build_scaling_params_for_context(
-+ const struct dc *dc,
-+ struct validate_context *context);
-+
-+void unreference_clock_source(
-+ struct resource_context *res_ctx,
-+ struct clock_source *clock_source);
-+
-+void reference_clock_source(
-+ struct resource_context *res_ctx,
-+ struct clock_source *clock_source);
-+
-+bool is_same_timing(
-+ const struct dc_crtc_timing *timing1,
-+ const struct dc_crtc_timing *timing2);
-+
-+struct clock_source *find_used_clk_src_for_sharing(
-+ struct validate_context *context,
-+ struct core_stream *stream);
-+
-+bool logical_attach_surfaces_to_target(
-+ struct dc_surface *surfaces[],
-+ uint8_t surface_count,
-+ struct dc_target *dc_target);
-+
-+#endif /* DRIVERS_GPU_DRM_AMD_DAL_DEV_DC_INC_RESOURCE_H_ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/transform.h b/drivers/gpu/drm/amd/dal/dc/inc/transform.h
-new file mode 100644
-index 0000000..8e111ce
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/transform.h
-@@ -0,0 +1,81 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_TRANSFORM_H__
-+#define __DAL_TRANSFORM_H__
-+
-+#include "include/scaler_types.h"
-+#include "calcs/scaler_filter.h"
-+#include "grph_object_id.h"
-+
-+enum scaling_type {
-+ SCALING_TYPE_NO_SCALING = 0,
-+ SCALING_TYPE_UPSCALING,
-+ SCALING_TYPE_DOWNSCALING
-+};
-+
-+struct transform {
-+ struct dc_context *ctx;
-+ uint32_t inst;
-+ struct scaler_filter *filter;
-+};
-+
-+struct scaler_taps_and_ratio {
-+ uint32_t h_tap;
-+ uint32_t v_tap;
-+ uint32_t lo_ratio;
-+ uint32_t hi_ratio;
-+};
-+
-+struct scaler_taps {
-+ uint32_t h_tap;
-+ uint32_t v_tap;
-+};
-+
-+struct sclv_ratios_inits {
-+ uint32_t chroma_enable;
-+ uint32_t h_int_scale_ratio_luma;
-+ uint32_t h_int_scale_ratio_chroma;
-+ uint32_t v_int_scale_ratio_luma;
-+ uint32_t v_int_scale_ratio_chroma;
-+ struct init_int_and_frac h_init_luma;
-+ struct init_int_and_frac h_init_chroma;
-+ struct init_int_and_frac v_init_luma;
-+ struct init_int_and_frac v_init_chroma;
-+ struct init_int_and_frac h_init_lumabottom;
-+ struct init_int_and_frac h_init_chromabottom;
-+ struct init_int_and_frac v_init_lumabottom;
-+ struct init_int_and_frac v_init_chromabottom;
-+};
-+
-+enum lb_pixel_depth {
-+ /* do not change the values because it is used as bit vector */
-+ LB_PIXEL_DEPTH_18BPP = 1,
-+ LB_PIXEL_DEPTH_24BPP = 2,
-+ LB_PIXEL_DEPTH_30BPP = 4,
-+ LB_PIXEL_DEPTH_36BPP = 8
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/irq/Makefile b/drivers/gpu/drm/amd/dal/dc/irq/Makefile
-new file mode 100644
-index 0000000..f1c5faf
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/irq/Makefile
-@@ -0,0 +1,21 @@
-+#
-+# Makefile for the 'audio' sub-component of DAL.
-+# It provides the control and status of HW adapter resources,
-+# that are global for the ASIC and sharable between pipes.
-+
-+IRQ = irq_service.o
-+
-+AMD_DAL_IRQ = $(addprefix $(AMDDALPATH)/dc/irq/,$(IRQ))
-+
-+AMD_DAL_FILES += $(AMD_DAL_IRQ)
-+
-+###############################################################################
-+# DCE 11x
-+###############################################################################
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_0
-+IRQ_DCE11 = irq_service_dce110.o
-+
-+AMD_DAL_IRQ_DCE11 = $(addprefix $(AMDDALPATH)/dc/irq/dce110/,$(IRQ_DCE11))
-+
-+AMD_DAL_FILES += $(AMD_DAL_IRQ_DCE11)
-+endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.c b/drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.c
-new file mode 100644
-index 0000000..2a4f14c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.c
-@@ -0,0 +1,389 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "include/logger_interface.h"
-+
-+#include "irq_service_dce110.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+#include "ivsrcid/ivsrcid_vislands30.h"
-+
-+static bool hpd_ack(
-+ struct irq_service *irq_service,
-+ const struct irq_source_info *info)
-+{
-+ uint32_t addr = info->status_reg;
-+ uint32_t value = dal_read_reg(irq_service->ctx, addr);
-+ uint32_t current_status =
-+ get_reg_field_value(
-+ value,
-+ DC_HPD_INT_STATUS,
-+ DC_HPD_SENSE_DELAYED);
-+
-+ dal_irq_service_ack_generic(irq_service, info);
-+
-+ value = dal_read_reg(irq_service->ctx, info->enable_reg);
-+
-+ set_reg_field_value(
-+ value,
-+ current_status ? 0 : 1,
-+ DC_HPD_INT_CONTROL,
-+ DC_HPD_INT_POLARITY);
-+
-+ dal_write_reg(irq_service->ctx, info->enable_reg, value);
-+
-+ return true;
-+}
-+
-+static const struct irq_source_info_funcs hpd_irq_info_funcs = {
-+ .set = NULL,
-+ .ack = hpd_ack
-+};
-+
-+static const struct irq_source_info_funcs hpd_rx_irq_info_funcs = {
-+ .set = NULL,
-+ .ack = NULL
-+};
-+
-+static const struct irq_source_info_funcs pflip_irq_info_funcs = {
-+ .set = NULL,
-+ .ack = NULL
-+};
-+
-+static const struct irq_source_info_funcs vblank_irq_info_funcs = {
-+ .set = NULL,
-+ .ack = NULL
-+};
-+
-+#define hpd_int_entry(reg_num)\
-+ [DC_IRQ_SOURCE_HPD1 + reg_num] = {\
-+ .enable_reg = mmHPD ## reg_num ## _DC_HPD_INT_CONTROL,\
-+ .enable_mask = DC_HPD_INT_CONTROL__DC_HPD_INT_EN_MASK,\
-+ .enable_value = {\
-+ DC_HPD_INT_CONTROL__DC_HPD_INT_EN_MASK,\
-+ ~DC_HPD_INT_CONTROL__DC_HPD_INT_EN_MASK\
-+ },\
-+ .ack_reg = mmHPD ## reg_num ## _DC_HPD_INT_CONTROL,\
-+ .ack_mask = DC_HPD_INT_CONTROL__DC_HPD_INT_ACK_MASK,\
-+ .ack_value = DC_HPD_INT_CONTROL__DC_HPD_INT_ACK_MASK,\
-+ .status_reg = mmHPD ## reg_num ## _DC_HPD_INT_STATUS,\
-+ .funcs = &hpd_irq_info_funcs\
-+ }
-+
-+#define hpd_rx_int_entry(reg_num)\
-+ [DC_IRQ_SOURCE_HPD1RX + reg_num] = {\
-+ .enable_reg = mmHPD ## reg_num ## _DC_HPD_INT_CONTROL,\
-+ .enable_mask = DC_HPD_INT_CONTROL__DC_HPD_RX_INT_EN_MASK,\
-+ .enable_value = {\
-+ DC_HPD_INT_CONTROL__DC_HPD_RX_INT_EN_MASK,\
-+ ~DC_HPD_INT_CONTROL__DC_HPD_RX_INT_EN_MASK },\
-+ .ack_reg = mmHPD ## reg_num ## _DC_HPD_INT_CONTROL,\
-+ .ack_mask = DC_HPD_INT_CONTROL__DC_HPD_RX_INT_ACK_MASK,\
-+ .ack_value = DC_HPD_INT_CONTROL__DC_HPD_RX_INT_ACK_MASK,\
-+ .status_reg = mmHPD ## reg_num ## _DC_HPD_INT_STATUS,\
-+ .funcs = &hpd_rx_irq_info_funcs\
-+ }
-+#define pflip_int_entry(reg_num)\
-+ [DC_IRQ_SOURCE_PFLIP1 + reg_num] = {\
-+ .enable_reg = mmDCP ## reg_num ## _GRPH_INTERRUPT_CONTROL,\
-+ .enable_mask =\
-+ GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK,\
-+ .enable_value = {\
-+ GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK,\
-+ ~GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK},\
-+ .ack_reg = mmDCP ## reg_num ## _GRPH_INTERRUPT_STATUS,\
-+ .ack_mask = GRPH_INTERRUPT_STATUS__GRPH_PFLIP_INT_CLEAR_MASK,\
-+ .ack_value = GRPH_INTERRUPT_STATUS__GRPH_PFLIP_INT_CLEAR_MASK,\
-+ .status_reg = mmDCP ## reg_num ##_GRPH_INTERRUPT_STATUS,\
-+ .funcs = &pflip_irq_info_funcs\
-+ }
-+
-+#define vsync_int_entry(reg_num) \
-+ [DC_IRQ_SOURCE_CRTC ## reg_num ## VSYNC] = dummy_irq_entry()
-+
-+#define vupdate_int_entry(reg_num)\
-+ [DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\
-+ .enable_reg = mmCRTC ## reg_num ## _CRTC_INTERRUPT_CONTROL,\
-+ .enable_mask =\
-+ CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK,\
-+ .enable_value = {\
-+ CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK,\
-+ ~CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK},\
-+ .ack_reg = mmCRTC ## reg_num ## _CRTC_V_UPDATE_INT_STATUS,\
-+ .ack_mask =\
-+ CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\
-+ .ack_value =\
-+ CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\
-+ .funcs = &vblank_irq_info_funcs\
-+ }
-+
-+#define dummy_irq_entry() \
-+ {\
-+ .funcs = &dummy_irq_info_funcs\
-+ }
-+
-+#define i2c_int_entry(reg_num) \
-+ [DC_IRQ_SOURCE_I2C_DDC ## reg_num] = dummy_irq_entry()
-+
-+#define azalia_int_entry(reg_num) \
-+ [DC_IRQ_SOURCE_AZALIA ## reg_num] = dummy_irq_entry()
-+
-+#define dp_sink_int_entry(reg_num) \
-+ [DC_IRQ_SOURCE_DPSINK ## reg_num] = dummy_irq_entry()
-+
-+#define gpio_pad_int_entry(reg_num) \
-+ [DC_IRQ_SOURCE_GPIOPAD ## reg_num] = dummy_irq_entry()
-+
-+#define dc_underflow_int_entry(reg_num) \
-+ [DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW] = dummy_irq_entry()
-+
-+static bool dummy_set(
-+ struct irq_service *irq_service,
-+ const struct irq_source_info *info,
-+ bool enable)
-+{
-+ dal_logger_write(
-+ irq_service->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_IRQ_SERVICE,
-+ "%s: called for non-implemented irq source\n",
-+ __func__);
-+ return false;
-+}
-+
-+static bool dummy_ack(
-+ struct irq_service *irq_service,
-+ const struct irq_source_info *info)
-+{
-+ dal_logger_write(
-+ irq_service->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_IRQ_SERVICE,
-+ "%s: called for non-implemented irq source\n",
-+ __func__);
-+ return false;
-+}
-+
-+static const struct irq_source_info_funcs dummy_irq_info_funcs = {
-+ .set = dummy_set,
-+ .ack = dummy_ack
-+};
-+
-+static const struct irq_source_info
-+irq_source_info_dce110[DAL_IRQ_SOURCES_NUMBER] = {
-+ [DC_IRQ_SOURCE_INVALID] = dummy_irq_entry(),
-+ hpd_int_entry(0),
-+ hpd_int_entry(1),
-+ hpd_int_entry(2),
-+ hpd_int_entry(3),
-+ hpd_int_entry(4),
-+ hpd_int_entry(5),
-+ hpd_rx_int_entry(0),
-+ hpd_rx_int_entry(1),
-+ hpd_rx_int_entry(2),
-+ hpd_rx_int_entry(3),
-+ hpd_rx_int_entry(4),
-+ hpd_rx_int_entry(5),
-+ i2c_int_entry(1),
-+ i2c_int_entry(2),
-+ i2c_int_entry(3),
-+ i2c_int_entry(4),
-+ i2c_int_entry(5),
-+ i2c_int_entry(6),
-+ azalia_int_entry(0),
-+ azalia_int_entry(1),
-+ azalia_int_entry(2),
-+ azalia_int_entry(3),
-+ azalia_int_entry(4),
-+ azalia_int_entry(5),
-+ dp_sink_int_entry(1),
-+ dp_sink_int_entry(2),
-+ dp_sink_int_entry(3),
-+ dp_sink_int_entry(4),
-+ dp_sink_int_entry(5),
-+ dp_sink_int_entry(6),
-+ vsync_int_entry(1),
-+ vsync_int_entry(2),
-+ vsync_int_entry(3),
-+ vsync_int_entry(3),
-+ vsync_int_entry(4),
-+ vsync_int_entry(5),
-+ [DC_IRQ_SOURCE_TIMER] = dummy_irq_entry(),
-+ pflip_int_entry(0),
-+ pflip_int_entry(1),
-+ pflip_int_entry(2),
-+ pflip_int_entry(3),
-+ pflip_int_entry(4),
-+ pflip_int_entry(5),
-+ [DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(),
-+ gpio_pad_int_entry(0),
-+ gpio_pad_int_entry(1),
-+ gpio_pad_int_entry(2),
-+ gpio_pad_int_entry(3),
-+ gpio_pad_int_entry(4),
-+ gpio_pad_int_entry(5),
-+ gpio_pad_int_entry(6),
-+ gpio_pad_int_entry(7),
-+ gpio_pad_int_entry(8),
-+ gpio_pad_int_entry(9),
-+ gpio_pad_int_entry(10),
-+ gpio_pad_int_entry(11),
-+ gpio_pad_int_entry(12),
-+ gpio_pad_int_entry(13),
-+ gpio_pad_int_entry(14),
-+ gpio_pad_int_entry(15),
-+ gpio_pad_int_entry(16),
-+ gpio_pad_int_entry(17),
-+ gpio_pad_int_entry(18),
-+ gpio_pad_int_entry(19),
-+ gpio_pad_int_entry(20),
-+ gpio_pad_int_entry(21),
-+ gpio_pad_int_entry(22),
-+ gpio_pad_int_entry(23),
-+ gpio_pad_int_entry(24),
-+ gpio_pad_int_entry(25),
-+ gpio_pad_int_entry(26),
-+ gpio_pad_int_entry(27),
-+ gpio_pad_int_entry(28),
-+ gpio_pad_int_entry(29),
-+ gpio_pad_int_entry(30),
-+ dc_underflow_int_entry(1),
-+ dc_underflow_int_entry(2),
-+ dc_underflow_int_entry(3),
-+ dc_underflow_int_entry(4),
-+ dc_underflow_int_entry(5),
-+ dc_underflow_int_entry(6),
-+ [DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(),
-+ [DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(),
-+ vupdate_int_entry(0),
-+ vupdate_int_entry(1),
-+ vupdate_int_entry(2),
-+ vupdate_int_entry(3),
-+ vupdate_int_entry(4),
-+ vupdate_int_entry(5),
-+};
-+
-+static enum dc_irq_source to_dal_irq_source(
-+ struct irq_service *irq_service,
-+ uint32_t src_id,
-+ uint32_t ext_id)
-+{
-+ switch (src_id) {
-+ case VISLANDS30_IV_SRCID_D1_V_UPDATE_INT:
-+ return DC_IRQ_SOURCE_VUPDATE1;
-+ case VISLANDS30_IV_SRCID_D2_V_UPDATE_INT:
-+ return DC_IRQ_SOURCE_VUPDATE2;
-+ case VISLANDS30_IV_SRCID_D3_V_UPDATE_INT:
-+ return DC_IRQ_SOURCE_VUPDATE3;
-+ case VISLANDS30_IV_SRCID_D4_V_UPDATE_INT:
-+ return DC_IRQ_SOURCE_VUPDATE4;
-+ case VISLANDS30_IV_SRCID_D5_V_UPDATE_INT:
-+ return DC_IRQ_SOURCE_VUPDATE5;
-+ case VISLANDS30_IV_SRCID_D6_V_UPDATE_INT:
-+ return DC_IRQ_SOURCE_VUPDATE6;
-+ case VISLANDS30_IV_SRCID_D1_GRPH_PFLIP:
-+ return DC_IRQ_SOURCE_PFLIP1;
-+ case VISLANDS30_IV_SRCID_D2_GRPH_PFLIP:
-+ return DC_IRQ_SOURCE_PFLIP2;
-+ case VISLANDS30_IV_SRCID_D3_GRPH_PFLIP:
-+ return DC_IRQ_SOURCE_PFLIP3;
-+ case VISLANDS30_IV_SRCID_D4_GRPH_PFLIP:
-+ return DC_IRQ_SOURCE_PFLIP4;
-+ case VISLANDS30_IV_SRCID_D5_GRPH_PFLIP:
-+ return DC_IRQ_SOURCE_PFLIP5;
-+ case VISLANDS30_IV_SRCID_D6_GRPH_PFLIP:
-+ return DC_IRQ_SOURCE_PFLIP6;
-+
-+ case VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A:
-+ /* generic src_id for all HPD and HPDRX interrupts */
-+ switch (ext_id) {
-+ case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_A:
-+ return DC_IRQ_SOURCE_HPD1;
-+ case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_B:
-+ return DC_IRQ_SOURCE_HPD2;
-+ case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_C:
-+ return DC_IRQ_SOURCE_HPD3;
-+ case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_D:
-+ return DC_IRQ_SOURCE_HPD4;
-+ case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_E:
-+ return DC_IRQ_SOURCE_HPD5;
-+ case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_F:
-+ return DC_IRQ_SOURCE_HPD6;
-+ case VISLANDS30_IV_EXTID_HPD_RX_A:
-+ return DC_IRQ_SOURCE_HPD1RX;
-+ case VISLANDS30_IV_EXTID_HPD_RX_B:
-+ return DC_IRQ_SOURCE_HPD2RX;
-+ case VISLANDS30_IV_EXTID_HPD_RX_C:
-+ return DC_IRQ_SOURCE_HPD3RX;
-+ case VISLANDS30_IV_EXTID_HPD_RX_D:
-+ return DC_IRQ_SOURCE_HPD4RX;
-+ case VISLANDS30_IV_EXTID_HPD_RX_E:
-+ return DC_IRQ_SOURCE_HPD5RX;
-+ case VISLANDS30_IV_EXTID_HPD_RX_F:
-+ return DC_IRQ_SOURCE_HPD6RX;
-+ default:
-+ return DC_IRQ_SOURCE_INVALID;
-+ }
-+ break;
-+
-+ default:
-+ return DC_IRQ_SOURCE_INVALID;
-+ }
-+}
-+
-+static const struct irq_service_funcs irq_service_funcs_dce110 = {
-+ .to_dal_irq_source = to_dal_irq_source
-+};
-+
-+bool construct(
-+ struct irq_service *irq_service,
-+ struct irq_service_init_data *init_data)
-+{
-+ if (!dal_irq_service_construct(irq_service, init_data))
-+ return false;
-+
-+ irq_service->info = irq_source_info_dce110;
-+ irq_service->funcs = &irq_service_funcs_dce110;
-+
-+ return true;
-+}
-+
-+struct irq_service *dal_irq_service_dce110_create(
-+ struct irq_service_init_data *init_data)
-+{
-+ struct irq_service *irq_service = dc_service_alloc(init_data->ctx, sizeof(*irq_service));
-+
-+ if (!irq_service)
-+ return NULL;
-+
-+ if (construct(irq_service, init_data))
-+ return irq_service;
-+
-+ dc_service_free(init_data->ctx, irq_service);
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.h b/drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.h
-new file mode 100644
-index 0000000..d6c28e9
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.h
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_IRQ_SERVICE_DCE110_H__
-+#define __DAL_IRQ_SERVICE_DCE110_H__
-+
-+#include "../irq_service.h"
-+
-+struct irq_service *dal_irq_service_dce110_create(
-+ struct irq_service_init_data *init_data);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/irq/irq_service.c b/drivers/gpu/drm/amd/dal/dc/irq/irq_service.c
-new file mode 100644
-index 0000000..0c7429c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/irq/irq_service.c
-@@ -0,0 +1,173 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dal_services.h"
-+
-+#include "include/irq_service_interface.h"
-+#include "include/logger_interface.h"
-+
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+#include "dce110/irq_service_dce110.h"
-+#endif
-+
-+#include "irq_service.h"
-+
-+bool dal_irq_service_construct(
-+ struct irq_service *irq_service,
-+ struct irq_service_init_data *init_data)
-+{
-+ if (!init_data || !init_data->ctx)
-+ return false;
-+
-+ irq_service->ctx = init_data->ctx;
-+ return true;
-+}
-+
-+struct irq_service *dal_irq_service_create(
-+ enum dce_version version,
-+ struct irq_service_init_data *init_data)
-+{
-+ switch (version) {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ case DCE_VERSION_11_0:
-+ return dal_irq_service_dce110_create(init_data);
-+#endif
-+ default:
-+ return NULL;
-+ }
-+}
-+
-+void dal_irq_service_destroy(struct irq_service **irq_service)
-+{
-+ if (!irq_service || !*irq_service) {
-+ BREAK_TO_DEBUGGER();
-+ return;
-+ }
-+
-+ dc_service_free((*irq_service)->ctx, *irq_service);
-+
-+ *irq_service = NULL;
-+}
-+
-+const struct irq_source_info *find_irq_source_info(
-+ struct irq_service *irq_service,
-+ enum dc_irq_source source)
-+{
-+ if (source > DAL_IRQ_SOURCES_NUMBER || source < DC_IRQ_SOURCE_INVALID)
-+ return NULL;
-+
-+ return &irq_service->info[source];
-+}
-+
-+void dal_irq_service_set_generic(
-+ struct irq_service *irq_service,
-+ const struct irq_source_info *info,
-+ bool enable)
-+{
-+ uint32_t addr = info->enable_reg;
-+ uint32_t value = dal_read_reg(irq_service->ctx, addr);
-+
-+ value = (value & ~info->enable_mask) |
-+ (info->enable_value[enable ? 0 : 1] & info->enable_mask);
-+ dal_write_reg(irq_service->ctx, addr, value);
-+}
-+
-+bool dal_irq_service_set(
-+ struct irq_service *irq_service,
-+ enum dc_irq_source source,
-+ bool enable)
-+{
-+ const struct irq_source_info *info =
-+ find_irq_source_info(irq_service, source);
-+
-+ if (!info) {
-+ dal_logger_write(
-+ irq_service->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_IRQ_SERVICE,
-+ "%s: cannot find irq info table entry for %d\n",
-+ __func__,
-+ source);
-+ return false;
-+ }
-+
-+ dal_irq_service_ack(irq_service, source);
-+
-+ if (info->funcs->set)
-+ return info->funcs->set(irq_service, info, enable);
-+
-+ dal_irq_service_set_generic(irq_service, info, enable);
-+
-+ return true;
-+}
-+
-+void dal_irq_service_ack_generic(
-+ struct irq_service *irq_service,
-+ const struct irq_source_info *info)
-+{
-+ uint32_t addr = info->ack_reg;
-+ uint32_t value = dal_read_reg(irq_service->ctx, addr);
-+
-+ value = (value & ~info->ack_mask) |
-+ (info->ack_value & info->ack_mask);
-+ dal_write_reg(irq_service->ctx, addr, value);
-+}
-+
-+bool dal_irq_service_ack(
-+ struct irq_service *irq_service,
-+ enum dc_irq_source source)
-+{
-+ const struct irq_source_info *info =
-+ find_irq_source_info(irq_service, source);
-+
-+ if (!info) {
-+ dal_logger_write(
-+ irq_service->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_IRQ_SERVICE,
-+ "%s: cannot find irq info table entry for %d\n",
-+ __func__,
-+ source);
-+ return false;
-+ }
-+
-+ if (info->funcs->ack)
-+ return info->funcs->ack(irq_service, info);
-+
-+ dal_irq_service_ack_generic(irq_service, info);
-+
-+ return true;
-+}
-+
-+enum dc_irq_source dal_irq_service_to_irq_source(
-+ struct irq_service *irq_service,
-+ uint32_t src_id,
-+ uint32_t ext_id)
-+{
-+ return irq_service->funcs->to_dal_irq_source(
-+ irq_service,
-+ src_id,
-+ ext_id);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/irq/irq_service.h b/drivers/gpu/drm/amd/dal/dc/irq/irq_service.h
-new file mode 100644
-index 0000000..a2a2d69
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/irq/irq_service.h
-@@ -0,0 +1,85 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_IRQ_SERVICE_H__
-+#define __DAL_IRQ_SERVICE_H__
-+
-+#include "include/irq_service_interface.h"
-+
-+#include "irq_types.h"
-+
-+struct irq_service;
-+struct irq_source_info;
-+
-+struct irq_source_info_funcs {
-+ bool (*set)(
-+ struct irq_service *irq_service,
-+ const struct irq_source_info *info,
-+ bool enable);
-+ bool (*ack)(
-+ struct irq_service *irq_service,
-+ const struct irq_source_info *info);
-+};
-+
-+struct irq_source_info {
-+ uint32_t src_id;
-+ uint32_t ext_id;
-+ uint32_t enable_reg;
-+ uint32_t enable_mask;
-+ uint32_t enable_value[2];
-+ uint32_t ack_reg;
-+ uint32_t ack_mask;
-+ uint32_t ack_value;
-+ uint32_t status_reg;
-+ const struct irq_source_info_funcs *funcs;
-+};
-+
-+struct irq_service_funcs {
-+ enum dc_irq_source (*to_dal_irq_source)(
-+ struct irq_service *irq_service,
-+ uint32_t src_id,
-+ uint32_t ext_id);
-+};
-+
-+struct irq_service {
-+ struct dc_context *ctx;
-+ const struct irq_source_info *info;
-+ const struct irq_service_funcs *funcs;
-+};
-+
-+bool dal_irq_service_construct(
-+ struct irq_service *irq_service,
-+ struct irq_service_init_data *init_data);
-+
-+void dal_irq_service_ack_generic(
-+ struct irq_service *irq_service,
-+ const struct irq_source_info *info);
-+
-+void dal_irq_service_set_generic(
-+ struct irq_service *irq_service,
-+ const struct irq_source_info *info,
-+ bool enable);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/irq_types.h b/drivers/gpu/drm/amd/dal/dc/irq_types.h
-new file mode 100644
-index 0000000..051a1f6
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/irq_types.h
-@@ -0,0 +1,199 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_IRQ_TYPES_H__
-+#define __DAL_IRQ_TYPES_H__
-+
-+struct dc_context;
-+
-+typedef void (*interrupt_handler)(void *);
-+
-+typedef void *irq_handler_idx;
-+#define DAL_INVALID_IRQ_HANDLER_IDX NULL
-+
-+
-+/* The order of the IRQ sources is important and MUST match the one's
-+of base driver */
-+enum dc_irq_source {
-+ /* Use as mask to specify invalid irq source */
-+ DC_IRQ_SOURCE_INVALID = 0,
-+
-+ DC_IRQ_SOURCE_HPD1,
-+ DC_IRQ_SOURCE_HPD2,
-+ DC_IRQ_SOURCE_HPD3,
-+ DC_IRQ_SOURCE_HPD4,
-+ DC_IRQ_SOURCE_HPD5,
-+ DC_IRQ_SOURCE_HPD6,
-+
-+ DC_IRQ_SOURCE_HPD1RX,
-+ DC_IRQ_SOURCE_HPD2RX,
-+ DC_IRQ_SOURCE_HPD3RX,
-+ DC_IRQ_SOURCE_HPD4RX,
-+ DC_IRQ_SOURCE_HPD5RX,
-+ DC_IRQ_SOURCE_HPD6RX,
-+
-+ DC_IRQ_SOURCE_I2C_DDC1,
-+ DC_IRQ_SOURCE_I2C_DDC2,
-+ DC_IRQ_SOURCE_I2C_DDC3,
-+ DC_IRQ_SOURCE_I2C_DDC4,
-+ DC_IRQ_SOURCE_I2C_DDC5,
-+ DC_IRQ_SOURCE_I2C_DDC6,
-+
-+ DC_IRQ_SOURCE_AZALIA0,
-+ DC_IRQ_SOURCE_AZALIA1,
-+ DC_IRQ_SOURCE_AZALIA2,
-+ DC_IRQ_SOURCE_AZALIA3,
-+ DC_IRQ_SOURCE_AZALIA4,
-+ DC_IRQ_SOURCE_AZALIA5,
-+
-+ DC_IRQ_SOURCE_DPSINK1,
-+ DC_IRQ_SOURCE_DPSINK2,
-+ DC_IRQ_SOURCE_DPSINK3,
-+ DC_IRQ_SOURCE_DPSINK4,
-+ DC_IRQ_SOURCE_DPSINK5,
-+ DC_IRQ_SOURCE_DPSINK6,
-+
-+ DC_IRQ_SOURCE_CRTC1VSYNC,
-+ DC_IRQ_SOURCE_CRTC2VSYNC,
-+ DC_IRQ_SOURCE_CRTC3VSYNC,
-+ DC_IRQ_SOURCE_CRTC4VSYNC,
-+ DC_IRQ_SOURCE_CRTC5VSYNC,
-+ DC_IRQ_SOURCE_CRTC6VSYNC,
-+ DC_IRQ_SOURCE_TIMER,
-+
-+ DC_IRQ_SOURCE_PFLIP_FIRST,
-+ DC_IRQ_SOURCE_PFLIP1 = DC_IRQ_SOURCE_PFLIP_FIRST,
-+ DC_IRQ_SOURCE_PFLIP2,
-+ DC_IRQ_SOURCE_PFLIP3,
-+ DC_IRQ_SOURCE_PFLIP4,
-+ DC_IRQ_SOURCE_PFLIP5,
-+ DC_IRQ_SOURCE_PFLIP6,
-+ DC_IRQ_SOURCE_PFLIP_UNDERLAY0,
-+ DC_IRQ_SOURCE_PFLIP_LAST = DC_IRQ_SOURCE_PFLIP_UNDERLAY0,
-+
-+ DC_IRQ_SOURCE_GPIOPAD0,
-+ DC_IRQ_SOURCE_GPIOPAD1,
-+ DC_IRQ_SOURCE_GPIOPAD2,
-+ DC_IRQ_SOURCE_GPIOPAD3,
-+ DC_IRQ_SOURCE_GPIOPAD4,
-+ DC_IRQ_SOURCE_GPIOPAD5,
-+ DC_IRQ_SOURCE_GPIOPAD6,
-+ DC_IRQ_SOURCE_GPIOPAD7,
-+ DC_IRQ_SOURCE_GPIOPAD8,
-+ DC_IRQ_SOURCE_GPIOPAD9,
-+ DC_IRQ_SOURCE_GPIOPAD10,
-+ DC_IRQ_SOURCE_GPIOPAD11,
-+ DC_IRQ_SOURCE_GPIOPAD12,
-+ DC_IRQ_SOURCE_GPIOPAD13,
-+ DC_IRQ_SOURCE_GPIOPAD14,
-+ DC_IRQ_SOURCE_GPIOPAD15,
-+ DC_IRQ_SOURCE_GPIOPAD16,
-+ DC_IRQ_SOURCE_GPIOPAD17,
-+ DC_IRQ_SOURCE_GPIOPAD18,
-+ DC_IRQ_SOURCE_GPIOPAD19,
-+ DC_IRQ_SOURCE_GPIOPAD20,
-+ DC_IRQ_SOURCE_GPIOPAD21,
-+ DC_IRQ_SOURCE_GPIOPAD22,
-+ DC_IRQ_SOURCE_GPIOPAD23,
-+ DC_IRQ_SOURCE_GPIOPAD24,
-+ DC_IRQ_SOURCE_GPIOPAD25,
-+ DC_IRQ_SOURCE_GPIOPAD26,
-+ DC_IRQ_SOURCE_GPIOPAD27,
-+ DC_IRQ_SOURCE_GPIOPAD28,
-+ DC_IRQ_SOURCE_GPIOPAD29,
-+ DC_IRQ_SOURCE_GPIOPAD30,
-+
-+ DC_IRQ_SOURCE_DC1UNDERFLOW,
-+ DC_IRQ_SOURCE_DC2UNDERFLOW,
-+ DC_IRQ_SOURCE_DC3UNDERFLOW,
-+ DC_IRQ_SOURCE_DC4UNDERFLOW,
-+ DC_IRQ_SOURCE_DC5UNDERFLOW,
-+ DC_IRQ_SOURCE_DC6UNDERFLOW,
-+
-+ DC_IRQ_SOURCE_DMCU_SCP,
-+ DC_IRQ_SOURCE_VBIOS_SW,
-+
-+ DC_IRQ_SOURCE_VUPDATE1,
-+ DC_IRQ_SOURCE_VUPDATE2,
-+ DC_IRQ_SOURCE_VUPDATE3,
-+ DC_IRQ_SOURCE_VUPDATE4,
-+ DC_IRQ_SOURCE_VUPDATE5,
-+ DC_IRQ_SOURCE_VUPDATE6,
-+
-+ DAL_IRQ_SOURCES_NUMBER
-+};
-+
-+enum irq_type
-+{
-+ IRQ_TYPE_PFLIP = DC_IRQ_SOURCE_PFLIP1,
-+ IRQ_TYPE_VUPDATE = DC_IRQ_SOURCE_VUPDATE1,
-+};
-+
-+#define DAL_VALID_IRQ_SRC_NUM(src) \
-+ ((src) <= DAL_IRQ_SOURCES_NUMBER && (src) > DC_IRQ_SOURCE_INVALID)
-+
-+/* Number of Page Flip IRQ Sources. */
-+#define DAL_PFLIP_IRQ_SRC_NUM \
-+ (DC_IRQ_SOURCE_PFLIP_LAST - DC_IRQ_SOURCE_PFLIP_FIRST + 1)
-+
-+/* the number of contexts may be expanded in the future based on needs */
-+enum dc_interrupt_context {
-+ INTERRUPT_LOW_IRQ_CONTEXT = 0,
-+ INTERRUPT_HIGH_IRQ_CONTEXT,
-+ INTERRUPT_CONTEXT_NUMBER
-+};
-+
-+enum dc_interrupt_porlarity {
-+ INTERRUPT_POLARITY_DEFAULT = 0,
-+ INTERRUPT_POLARITY_LOW = INTERRUPT_POLARITY_DEFAULT,
-+ INTERRUPT_POLARITY_HIGH,
-+ INTERRUPT_POLARITY_BOTH
-+};
-+
-+#define DC_DECODE_INTERRUPT_POLARITY(int_polarity) \
-+ (int_polarity == INTERRUPT_POLARITY_LOW) ? "Low" : \
-+ (int_polarity == INTERRUPT_POLARITY_HIGH) ? "High" : \
-+ (int_polarity == INTERRUPT_POLARITY_BOTH) ? "Both" : "Invalid"
-+
-+struct dc_timer_interrupt_params {
-+ uint64_t micro_sec_interval;
-+ enum dc_interrupt_context int_context;
-+};
-+
-+struct dc_interrupt_params {
-+ /* The polarity *change* which will trigger an interrupt.
-+ * If 'requested_polarity == INTERRUPT_POLARITY_BOTH', then
-+ * 'current_polarity' must be initialised. */
-+ enum dc_interrupt_porlarity requested_polarity;
-+ /* If 'requested_polarity == INTERRUPT_POLARITY_BOTH',
-+ * 'current_polarity' should contain the current state, which means
-+ * the interrupt will be triggered when state changes from what is,
-+ * in 'current_polarity'. */
-+ enum dc_interrupt_porlarity current_polarity;
-+ enum dc_irq_source irq_source;
-+ enum dc_interrupt_context int_context;
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/adapter_service_interface.h b/drivers/gpu/drm/amd/dal/include/adapter_service_interface.h
-new file mode 100644
-index 0000000..aa503a8
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/adapter_service_interface.h
-@@ -0,0 +1,628 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_ADAPTER_SERVICE_INTERFACE_H__
-+#define __DAL_ADAPTER_SERVICE_INTERFACE_H__
-+
-+#include "grph_object_ctrl_defs.h"
-+#include "gpio_interface.h"
-+#include "ddc_interface.h"
-+#include "irq_interface.h"
-+#include "bios_parser_interface.h"
-+#include "adapter_service_types.h"
-+#include "dal_types.h"
-+#include "asic_capability_types.h"
-+
-+/* forward declaration */
-+struct bios_parser;
-+struct i2caux;
-+struct adapter_service;
-+
-+
-+/*
-+ * enum adapter_feature_id
-+ *
-+ * Definition of all adapter features
-+ *
-+ * The enumeration defines the IDs of all the adapter features. The enum
-+ * organizes all the features into several feature sets. The range of feature
-+ * set N is from ((N-1)*32+1) to (N*32). Because there may be three value-type
-+ * feature, boolean-type, unsigned char-type and unsinged int-type, the number
-+ * of features should be 32, 4 and 1 in the feature set accordingly.
-+ *
-+ * In a boolean-type feature set N, the enumeration value of the feature should
-+ * be ((N-1)*32+1), ((N-1)*32+2), ..., (N*32).
-+ *
-+ * In an unsigned char-type feature set N, the enumeration value of the
-+ * feature should be ((N-1)*32+1), ((N-1)*32+8), ((N-1)*32+16) and (N*32).
-+ *
-+ * In an unsigned int-type feature set N, the enumeration value of the feature
-+ * should be ((N-1)*32+1)
-+ */
-+enum adapter_feature_id {
-+ FEATURE_UNKNOWN = 0,
-+
-+ /* Boolean set, up to 32 entries */
-+ FEATURE_ENABLE_HW_EDID_POLLING = 1,
-+ FEATURE_SET_01_START = FEATURE_ENABLE_HW_EDID_POLLING,
-+ FEATURE_DP_SINK_DETECT_POLL_DATA_PIN,
-+ FEATURE_UNDERFLOW_INTERRUPT,
-+ FEATURE_ALLOW_WATERMARK_ADJUSTMENT,
-+ FEATURE_LIGHT_SLEEP,
-+ FEATURE_DCP_DITHER_FRAME_RANDOM_ENABLE,
-+ FEATURE_DCP_DITHER_RGB_RANDOM_ENABLE,
-+ FEATURE_DCP_DITHER_HIGH_PASS_RANDOM_ENABLE,
-+ FEATURE_DETECT_REQUIRE_HPD_HIGH,
-+ FEATURE_LINE_BUFFER_ENHANCED_PIXEL_DEPTH, /* 10th */
-+ FEATURE_MAXIMIZE_URGENCY_WATERMARKS,
-+ FEATURE_MAXIMIZE_STUTTER_MARKS,
-+ FEATURE_MAXIMIZE_NBP_MARKS,
-+ FEATURE_RESTORE_USAGE_I2C_SW_ENGINE,
-+ FEATURE_USE_MAX_DISPLAY_CLK,
-+ FEATURE_ALLOW_EDP_RESOURCE_SHARING,
-+ FEATURE_SUPPORT_DP_YUV,
-+ FEATURE_SUPPORT_DP_Y_ONLY,
-+ FEATURE_DISABLE_DP_GTC_SYNC,
-+ FEATURE_NO_HPD_LOW_POLLING_VCC_OFF, /* 20th */
-+ FEATURE_ENABLE_DFS_BYPASS,
-+ FEATURE_LB_HIGH_RESOLUTION,
-+ FEATURE_DP_DISPLAY_FORCE_SS_ENABLE,
-+ FEATURE_REPORT_CE_MODE_ONLY,
-+ FEATURE_ALLOW_OPTIMIZED_MODE_AS_DEFAULT,
-+ FEATURE_DDC_READ_FORCE_REPEATED_START,
-+ FEATURE_FORCE_TIMING_RESYNC,
-+ FEATURE_TMDS_DISABLE_DITHERING,
-+ FEATURE_HDMI_DISABLE_DITHERING,
-+ FEATURE_DP_DISABLE_DITHERING, /* 30th */
-+ FEATURE_EMBEDDED_DISABLE_DITHERING,
-+ FEATURE_DISABLE_AZ_CLOCK_GATING, /* 32th. This set is full */
-+ FEATURE_SET_01_END = FEATURE_SET_01_START + 31,
-+
-+ /* Boolean set, up to 32 entries */
-+ FEATURE_WIRELESS_ENABLE = FEATURE_SET_01_END + 1,
-+ FEATURE_SET_02_START = FEATURE_WIRELESS_ENABLE,
-+ FEATURE_WIRELESS_FULL_TIMING_ADJUSTMENT,
-+ FEATURE_WIRELESS_LIMIT_720P,
-+ FEATURE_WIRELESS_ENABLE_COMPRESSED_AUDIO,
-+ FEATURE_WIRELESS_INCLUDE_UNVERIFIED_TIMINGS,
-+ FEATURE_MODIFY_TIMINGS_FOR_WIRELESS,
-+ FEATURE_ALLOW_SELF_REFRESH,
-+ FEATURE_ALLOW_DYNAMIC_PIXEL_ENCODING_CHANGE,
-+ FEATURE_ALLOW_HSYNC_VSYNC_ADJUSTMENT,
-+ FEATURE_FORCE_PSR, /* 10th */
-+ FEATURE_PREFER_3D_TIMING,
-+ FEATURE_VARI_BRIGHT_ENABLE,
-+ FEATURE_PSR_ENABLE,
-+ FEATURE_EDID_STRESS_READ,
-+ FEATURE_DP_FRAME_PACK_STEREO3D,
-+ FEATURE_ALLOW_HDMI_WITHOUT_AUDIO,
-+ FEATURE_RESTORE_USAGE_I2C_SW_ENGING,
-+ FEATURE_ABM_2_0,
-+ FEATURE_SUPPORT_MIRABILIS,
-+ FEATURE_LOAD_DMCU_FIRMWARE, /* 20th */
-+ FEATURE_ENABLE_GPU_SCALING,
-+ FEATURE_DONGLE_SINK_COUNT_CHECK,
-+ FEATURE_INSTANT_UP_SCALE_DOWN_SCALE,
-+ FEATURE_TILED_DISPLAY,
-+ FEATURE_CHANGE_I2C_SPEED_CONTROL,
-+ FEATURE_REPORT_SINGLE_SELECTED_TIMING,
-+ FEATURE_ALLOW_HDMI_HIGH_CLK_DP_DONGLE,
-+ FEATURE_SUPPORT_EXTERNAL_PANEL_DRR,
-+ FEATURE_SUPPORT_SMOOTH_BRIGHTNESS,
-+ FEATURE_ALLOW_DIRECT_MEMORY_ACCESS_TRIG, /* 30th */
-+ FEATURE_POWER_GATING_LB_PORTION, /* 31nd. One more left. */
-+ FEATURE_SET_02_END = FEATURE_SET_02_START + 31,
-+
-+ /* UInt set, 1 entry: DCP Bit Depth Reduction Mode */
-+ FEATURE_DCP_BIT_DEPTH_REDUCTION_MODE = FEATURE_SET_02_END + 1,
-+ FEATURE_SET_03_START = FEATURE_DCP_BIT_DEPTH_REDUCTION_MODE,
-+ FEATURE_SET_03_END = FEATURE_SET_03_START + 31,
-+
-+ /* UInt set, 1 entry: DCP Dither Mode */
-+ FEATURE_DCP_DITHER_MODE = FEATURE_SET_03_END + 1,
-+ FEATURE_SET_04_START = FEATURE_DCP_DITHER_MODE,
-+ FEATURE_SET_04_END = FEATURE_SET_04_START + 31,
-+
-+ /* UInt set, 1 entry: DCP Programming WA(workaround) */
-+ FEATURE_DCP_PROGRAMMING_WA = FEATURE_SET_04_END + 1,
-+ FEATURE_SET_06_START = FEATURE_DCP_PROGRAMMING_WA,
-+ FEATURE_SET_06_END = FEATURE_SET_06_START + 31,
-+
-+ /* UInt set, 1 entry: Maximum co-functional non-DP displays */
-+ FEATURE_MAX_COFUNC_NON_DP_DISPLAYS = FEATURE_SET_06_END + 1,
-+ FEATURE_SET_07_START = FEATURE_MAX_COFUNC_NON_DP_DISPLAYS,
-+ FEATURE_SET_07_END = FEATURE_SET_07_START + 31,
-+
-+ /* UInt set, 1 entry: Number of supported HDMI connection */
-+ FEATURE_SUPPORTED_HDMI_CONNECTION_NUM = FEATURE_SET_07_END + 1,
-+ FEATURE_SET_08_START = FEATURE_SUPPORTED_HDMI_CONNECTION_NUM,
-+ FEATURE_SET_08_END = FEATURE_SET_08_START + 31,
-+
-+ /* UInt set, 1 entry: Maximum number of controllers */
-+ FEATURE_MAX_CONTROLLER_NUM = FEATURE_SET_08_END + 1,
-+ FEATURE_SET_09_START = FEATURE_MAX_CONTROLLER_NUM,
-+ FEATURE_SET_09_END = FEATURE_SET_09_START + 31,
-+
-+ /* UInt set, 1 entry: Type of DRR support */
-+ FEATURE_DRR_SUPPORT = FEATURE_SET_09_END + 1,
-+ FEATURE_SET_10_START = FEATURE_DRR_SUPPORT,
-+ FEATURE_SET_10_END = FEATURE_SET_10_START + 31,
-+
-+ /* UInt set, 1 entry: Stutter mode support */
-+ FEATURE_STUTTER_MODE = FEATURE_SET_10_END + 1,
-+ FEATURE_SET_11_START = FEATURE_STUTTER_MODE,
-+ FEATURE_SET_11_END = FEATURE_SET_11_START + 31,
-+
-+ /* UInt set, 1 entry: Measure PSR setup time */
-+ FEATURE_PSR_SETUP_TIME_TEST = FEATURE_SET_11_END + 1,
-+ FEATURE_SET_12_START = FEATURE_PSR_SETUP_TIME_TEST,
-+ FEATURE_SET_12_END = FEATURE_SET_12_START + 31,
-+
-+ /* Boolean set, up to 32 entries */
-+ FEATURE_POWER_GATING_PIPE_IN_TILE = FEATURE_SET_12_END + 1,
-+ FEATURE_SET_13_START = FEATURE_POWER_GATING_PIPE_IN_TILE,
-+ FEATURE_USE_PPLIB,
-+ FEATURE_DISABLE_LPT_SUPPORT,
-+ FEATURE_DUMMY_FBC_BACKEND,
-+ FEATURE_DISABLE_FBC_COMP_CLK_GATE,
-+ FEATURE_DPMS_AUDIO_ENDPOINT_CONTROL,
-+ FEATURE_PIXEL_PERFECT_OUTPUT,
-+ FEATURE_8BPP_SUPPORTED,
-+ FEATURE_SET_13_END = FEATURE_SET_13_START + 31,
-+
-+ /* UInt set, 1 entry: Display preferred view
-+ * 0: no preferred view
-+ * 1: native and preferred timing of embedded display will have high
-+ * priority, so other displays will support it always
-+ */
-+ FEATURE_DISPLAY_PREFERRED_VIEW = FEATURE_SET_13_END + 1,
-+ FEATURE_SET_15_START = FEATURE_DISPLAY_PREFERRED_VIEW,
-+ FEATURE_SET_15_END = FEATURE_SET_15_START + 31,
-+
-+ /* UInt set, 1 entry: DAL optimization */
-+ FEATURE_OPTIMIZATION = FEATURE_SET_15_END + 1,
-+ FEATURE_SET_16_START = FEATURE_OPTIMIZATION,
-+ FEATURE_SET_16_END = FEATURE_SET_16_START + 31,
-+
-+ /* UInt set, 1 entry: Performance measurement */
-+ FEATURE_PERF_MEASURE = FEATURE_SET_16_END + 1,
-+ FEATURE_SET_17_START = FEATURE_PERF_MEASURE,
-+ FEATURE_SET_17_END = FEATURE_SET_17_START + 31,
-+
-+ /* UInt set, 1 entry: Minimum backlight value [0-255] */
-+ FEATURE_MIN_BACKLIGHT_LEVEL = FEATURE_SET_17_END + 1,
-+ FEATURE_SET_18_START = FEATURE_MIN_BACKLIGHT_LEVEL,
-+ FEATURE_SET_18_END = FEATURE_SET_18_START + 31,
-+
-+ /* UInt set, 1 entry: Maximum backlight value [0-255] */
-+ FEATURE_MAX_BACKLIGHT_LEVEL = FEATURE_SET_18_END + 1,
-+ FEATURE_SET_19_START = FEATURE_MAX_BACKLIGHT_LEVEL,
-+ FEATURE_SET_19_END = FEATURE_SET_19_START + 31,
-+
-+ /* UInt set, 1 entry: AMB setting
-+ *
-+ * Each byte will control the ABM configuration to use for a specific
-+ * ABM level.
-+ *
-+ * HW team provided 12 different ABM min/max reduction pairs to choose
-+ * between for each ABM level.
-+ *
-+ * ABM level Byte Setting
-+ * 1 0 Default = 0 (setting 3), can be override to 1-12
-+ * 2 1 Default = 0 (setting 7), can be override to 1-12
-+ * 3 2 Default = 0 (setting 8), can be override to 1-12
-+ * 4 3 Default = 0 (setting 10), can be override to 1-12
-+ *
-+ * For example,
-+ * FEATURE_PREFERRED_ABM_CONFIG_SET = 0x0C060500, this represents:
-+ * ABM level 1 use default setting (setting 3)
-+ * ABM level 2 uses setting 5
-+ * ABM level 3 uses setting 6
-+ * ABM level 4 uses setting 12
-+ * Internal use only!
-+ */
-+ FEATURE_PREFERRED_ABM_CONFIG_SET = FEATURE_SET_19_END + 1,
-+ FEATURE_SET_20_START = FEATURE_PREFERRED_ABM_CONFIG_SET,
-+ FEATURE_SET_20_END = FEATURE_SET_20_START + 31,
-+
-+ /* UInt set, 1 entry: Change SW I2C speed */
-+ FEATURE_CHANGE_SW_I2C_SPEED = FEATURE_SET_20_END + 1,
-+ FEATURE_SET_21_START = FEATURE_CHANGE_SW_I2C_SPEED,
-+ FEATURE_SET_21_END = FEATURE_SET_21_START + 31,
-+
-+ /* UInt set, 1 entry: Change HW I2C speed */
-+ FEATURE_CHANGE_HW_I2C_SPEED = FEATURE_SET_21_END + 1,
-+ FEATURE_SET_22_START = FEATURE_CHANGE_HW_I2C_SPEED,
-+ FEATURE_SET_22_END = FEATURE_SET_22_START + 31,
-+
-+ /* UInt set, 1 entry:
-+ * When PSR issue occurs, it is sometimes hard to debug since the
-+ * failure occurs immediately at boot. Use this setting to skip or
-+ * postpone PSR functionality and re-enable through DSAT. */
-+ FEATURE_DEFAULT_PSR_LEVEL = FEATURE_SET_22_END + 1,
-+ FEATURE_SET_23_START = FEATURE_DEFAULT_PSR_LEVEL,
-+ FEATURE_SET_23_END = FEATURE_SET_23_START + 31,
-+
-+ /* UInt set, 1 entry: Allowed pixel clock range for LVDS */
-+ FEATURE_LVDS_SAFE_PIXEL_CLOCK_RANGE = FEATURE_SET_23_END + 1,
-+ FEATURE_SET_24_START = FEATURE_LVDS_SAFE_PIXEL_CLOCK_RANGE,
-+ FEATURE_SET_24_END = FEATURE_SET_24_START + 31,
-+
-+ /* UInt set, 1 entry: Max number of clock sources */
-+ FEATURE_MAX_CLOCK_SOURCE_NUM = FEATURE_SET_24_END + 1,
-+ FEATURE_SET_25_START = FEATURE_MAX_CLOCK_SOURCE_NUM,
-+ FEATURE_SET_25_END = FEATURE_SET_25_START + 31,
-+
-+ /* UInt set, 1 entry: Select the ABM configuration to use.
-+ *
-+ * This feature set is used to allow packaging option to be defined
-+ * to allow OEM to select between the default ABM configuration or
-+ * alternative predefined configurations that may be more aggressive.
-+ *
-+ * Note that this regkey is meant for external use to select the
-+ * configuration OEM wants. Whereas the other PREFERRED_ABM_CONFIG_SET
-+ * key is only used for internal use and allows full reconfiguration.
-+ */
-+ FEATURE_ABM_CONFIG = FEATURE_SET_25_END + 1,
-+ FEATURE_SET_26_START = FEATURE_ABM_CONFIG,
-+ FEATURE_SET_26_END = FEATURE_SET_26_START + 31,
-+
-+ /* UInt set, 1 entry: Select the default speed in which smooth
-+ * brightness feature should converge towards target backlight level.
-+ *
-+ * For example, a setting of 500 means it takes 500ms to transition
-+ * from current backlight level to the new requested backlight level.
-+ */
-+ FEATURE_SMOOTH_BRTN_ADJ_TIME_IN_MS = FEATURE_SET_26_END + 1,
-+ FEATURE_SET_27_START = FEATURE_SMOOTH_BRTN_ADJ_TIME_IN_MS,
-+ FEATURE_SET_27_END = FEATURE_SET_27_START + 31,
-+
-+ /* Set 28: UInt set, 1 entry: Allow runtime parameter to force specific
-+ * Static Screen Event triggers for test purposes. */
-+ FEATURE_FORCE_STATIC_SCREEN_EVENT_TRIGGERS = FEATURE_SET_27_END + 1,
-+ FEATURE_SET_28_START = FEATURE_FORCE_STATIC_SCREEN_EVENT_TRIGGERS,
-+ FEATURE_SET_28_END = FEATURE_SET_28_START + 31,
-+
-+ FEATURE_MAXIMUM
-+};
-+
-+/* Adapter Service type of DRR support*/
-+enum as_drr_support {
-+ AS_DRR_SUPPORT_DISABLED = 0x0,
-+ AS_DRR_SUPPORT_ENABLED = 0x1,
-+ AS_DRR_SUPPORT_MIN_FORCED_FPS = 0xA
-+};
-+
-+/* Adapter service initialize data structure*/
-+struct as_init_data {
-+ struct hw_asic_id hw_init_data;
-+ struct bp_init_data bp_init_data;
-+ struct dc_context *ctx;
-+ struct bdf_info bdf_info;
-+ const struct dal_override_parameters *display_param;
-+};
-+
-+/* Create adapter service */
-+struct adapter_service *dal_adapter_service_create(
-+ struct as_init_data *init_data);
-+
-+/* Destroy adapter service and objects it contains */
-+void dal_adapter_service_destroy(
-+ struct adapter_service **as);
-+
-+/* Get the DCE version of current ASIC */
-+enum dce_version dal_adapter_service_get_dce_version(
-+ const struct adapter_service *as);
-+
-+/* Get firmware information from BIOS */
-+bool dal_adapter_service_get_firmware_info(
-+ struct adapter_service *as,
-+ struct firmware_info *info);
-+
-+
-+/* functions to get a total number of objects of specific type */
-+uint8_t dal_adapter_service_get_connectors_num(
-+ struct adapter_service *as);
-+
-+/* Get number of controllers */
-+uint8_t dal_adapter_service_get_controllers_num(
-+ struct adapter_service *as);
-+
-+/* Get number of clock sources */
-+uint8_t dal_adapter_service_get_clock_sources_num(
-+ struct adapter_service *as);
-+
-+/* Get number of controllers */
-+uint8_t dal_adapter_service_get_func_controllers_num(
-+ struct adapter_service *as);
-+
-+/* Get number of stream engines */
-+uint8_t dal_adapter_service_get_stream_engines_num(
-+ struct adapter_service *as);
-+
-+/* functions to get object id based on object index */
-+struct graphics_object_id dal_adapter_service_get_connector_obj_id(
-+ struct adapter_service *as,
-+ uint8_t connector_index);
-+
-+/* Get number of spread spectrum entries from BIOS */
-+uint32_t dal_adapter_service_get_ss_info_num(
-+ struct adapter_service *as,
-+ enum as_signal_type signal);
-+
-+/* Get spread spectrum info from BIOS */
-+bool dal_adapter_service_get_ss_info(
-+ struct adapter_service *as,
-+ enum as_signal_type signal,
-+ uint32_t idx,
-+ struct spread_spectrum_info *info);
-+
-+/* Check if DFS bypass is enabled */
-+bool dal_adapter_service_is_dfs_bypass_enabled(struct adapter_service *as);
-+
-+/* Get memory controller latency */
-+uint32_t dal_adapter_service_get_mc_latency(
-+ struct adapter_service *as);
-+
-+/* Get the video RAM bit width set on the ASIC */
-+uint32_t dal_adapter_service_get_asic_vram_bit_width(
-+ struct adapter_service *as);
-+
-+/* Get the bug flags set on this ASIC */
-+struct asic_bugs dal_adapter_service_get_asic_bugs(
-+ struct adapter_service *as);
-+
-+/* Get efficiency of DRAM */
-+uint32_t dal_adapter_service_get_dram_bandwidth_efficiency(
-+ struct adapter_service *as);
-+
-+/* Get multiplier for the memory type */
-+uint32_t dal_adapter_service_get_memory_type_multiplier(
-+ struct adapter_service *as);
-+
-+/* Get parameters for bandwidth tuning */
-+bool dal_adapter_service_get_bandwidth_tuning_params(
-+ struct adapter_service *as,
-+ union bandwidth_tuning_params *params);
-+
-+/* Get integrated information on BIOS */
-+bool dal_adapter_service_get_integrated_info(
-+ struct adapter_service *as,
-+ struct integrated_info *info);
-+
-+/* Return if a given feature is supported by the ASIC */
-+bool dal_adapter_service_is_feature_supported(
-+ enum adapter_feature_id feature_id);
-+
-+/* Get the cached value of a given feature */
-+bool dal_adapter_service_get_feature_value(
-+ const enum adapter_feature_id feature_id,
-+ void *data,
-+ uint32_t size);
-+
-+/* Get a copy of ASIC feature flags */
-+struct asic_feature_flags dal_adapter_service_get_feature_flags(
-+ struct adapter_service *as);
-+
-+/* Obtain DDC */
-+struct ddc *dal_adapter_service_obtain_ddc(
-+ struct adapter_service *as,
-+ struct graphics_object_id id);
-+
-+/* Release DDC */
-+void dal_adapter_service_release_ddc(
-+ struct adapter_service *as,
-+ struct ddc *ddc);
-+
-+/* Obtain HPD interrupt request */
-+struct irq *dal_adapter_service_obtain_hpd_irq(
-+ struct adapter_service *as,
-+ struct graphics_object_id id);
-+
-+/* Release interrupt request */
-+void dal_adapter_service_release_irq(
-+ struct adapter_service *as,
-+ struct irq *irq);
-+
-+/* Obtain GPIO */
-+struct gpio *dal_adapter_service_obtain_gpio(
-+ struct adapter_service *as,
-+ enum gpio_id id,
-+ uint32_t en);
-+
-+/* Obtain GPIO for stereo3D*/
-+struct gpio *dal_adapter_service_obtain_stereo_gpio(struct adapter_service *as);
-+
-+/* Release GPIO */
-+void dal_adapter_service_release_gpio(
-+ struct adapter_service *as,
-+ struct gpio *gpio);
-+
-+/* Get SW I2C speed */
-+uint32_t dal_adapter_service_get_sw_i2c_speed(struct adapter_service *as);
-+
-+/* Get HW I2C speed */
-+uint32_t dal_adapter_service_get_hw_i2c_speed(struct adapter_service *as);
-+
-+/* Get line buffer size */
-+uint32_t dal_adapter_service_get_line_buffer_size(struct adapter_service *as);
-+
-+/* Get information on audio support */
-+union audio_support dal_adapter_service_get_audio_support(
-+ struct adapter_service *as);
-+
-+/* Get I2C information from BIOS */
-+bool dal_adapter_service_get_i2c_info(
-+ struct adapter_service *as,
-+ struct graphics_object_id id,
-+ struct graphics_object_i2c_info *i2c_info);
-+
-+/* Get bios parser handler */
-+struct bios_parser *dal_adapter_service_get_bios_parser(
-+ struct adapter_service *as);
-+
-+/* Get i2c aux handler */
-+struct i2caux *dal_adapter_service_get_i2caux(
-+ struct adapter_service *as);
-+
-+struct dal_asic_runtime_flags dal_adapter_service_get_asic_runtime_flags(
-+ struct adapter_service *as);
-+
-+bool dal_adapter_service_initialize_hw_data(
-+ struct adapter_service *as);
-+
-+struct graphics_object_id dal_adapter_service_enum_fake_path_resource(
-+ struct adapter_service *as,
-+ uint32_t index);
-+
-+struct graphics_object_id dal_adapter_service_enum_stereo_sync_object(
-+ struct adapter_service *as,
-+ uint32_t index);
-+
-+struct graphics_object_id dal_adapter_service_enum_sync_output_object(
-+ struct adapter_service *as,
-+ uint32_t index);
-+
-+struct graphics_object_id dal_adapter_service_enum_audio_object(
-+ struct adapter_service *as,
-+ uint32_t index);
-+
-+void dal_adapter_service_update_audio_connectivity(
-+ struct adapter_service *as,
-+ uint32_t number_of_audio_capable_display_path);
-+
-+bool dal_adapter_service_has_embedded_display_connector(
-+ struct adapter_service *as);
-+
-+bool dal_adapter_service_get_embedded_panel_info(
-+ struct adapter_service *as,
-+ struct embedded_panel_info *info);
-+
-+bool dal_adapter_service_enum_embedded_panel_patch_mode(
-+ struct adapter_service *as,
-+ uint32_t index,
-+ struct embedded_panel_patch_mode *mode);
-+
-+bool dal_adapter_service_get_faked_edid_len(
-+ struct adapter_service *as,
-+ uint32_t *len);
-+
-+bool dal_adapter_service_get_faked_edid_buf(
-+ struct adapter_service *as,
-+ uint8_t *buf,
-+ uint32_t len);
-+
-+uint32_t dal_adapter_service_get_max_cofunc_non_dp_displays(void);
-+
-+uint32_t dal_adapter_service_get_single_selected_timing_signals(void);
-+
-+bool dal_adapter_service_get_device_tag(
-+ struct adapter_service *as,
-+ struct graphics_object_id connector_object_id,
-+ uint32_t device_tag_index,
-+ struct connector_device_tag_info *info);
-+
-+bool dal_adapter_service_is_device_id_supported(
-+ struct adapter_service *as,
-+ struct device_id id);
-+
-+bool dal_adapter_service_is_meet_underscan_req(struct adapter_service *as);
-+
-+bool dal_adapter_service_underscan_for_hdmi_only(struct adapter_service *as);
-+
-+uint32_t dal_adapter_service_get_src_num(
-+ struct adapter_service *as,
-+ struct graphics_object_id id);
-+
-+struct graphics_object_id dal_adapter_service_get_src_obj(
-+ struct adapter_service *as,
-+ struct graphics_object_id id,
-+ uint32_t index);
-+
-+/* Is this Fusion ASIC */
-+bool dal_adapter_service_is_fusion(struct adapter_service *as);
-+
-+/* Is this ASIC support dynamic DFSbypass switch */
-+bool dal_adapter_service_is_dfsbyass_dynamic(struct adapter_service *as);
-+
-+/* Reports whether driver settings allow requested optimization */
-+bool dal_adapter_service_should_optimize(
-+ struct adapter_service *as, enum optimization_feature feature);
-+
-+/* Determine if driver is in accelerated mode */
-+bool dal_adapter_service_is_in_accelerated_mode(struct adapter_service *as);
-+
-+struct ddc *dal_adapter_service_obtain_ddc_from_i2c_info(
-+ struct adapter_service *as,
-+ struct graphics_object_i2c_info *info);
-+
-+struct bdf_info dal_adapter_service_get_adapter_info(
-+ struct adapter_service *as);
-+
-+
-+/* Determine if this ASIC needs to wait on PLL lock bit */
-+bool dal_adapter_service_should_psr_skip_wait_for_pll_lock(
-+ struct adapter_service *as);
-+
-+#define SIZEOF_BACKLIGHT_LUT 101
-+#define ABSOLUTE_BACKLIGHT_MAX 255
-+#define DEFAULT_MIN_BACKLIGHT 12
-+#define DEFAULT_MAX_BACKLIGHT 255
-+#define BACKLIGHT_CURVE_COEFFB 100
-+#define BACKLIGHT_CURVE_COEFFA_FACTOR 10000
-+#define BACKLIGHT_CURVE_COEFFB_FACTOR 100
-+
-+struct panel_backlight_levels {
-+ uint32_t ac_level_percentage;
-+ uint32_t dc_level_percentage;
-+};
-+
-+bool dal_adapter_service_is_lid_open(struct adapter_service *as);
-+
-+bool dal_adapter_service_get_panel_backlight_default_levels(
-+ struct adapter_service *as,
-+ struct panel_backlight_levels *levels);
-+
-+bool dal_adapter_service_get_panel_backlight_boundaries(
-+ struct adapter_service *as,
-+ struct panel_backlight_boundaries *boundaries);
-+
-+uint32_t dal_adapter_service_get_view_port_pixel_granularity(
-+ struct adapter_service *as);
-+
-+uint32_t dal_adapter_service_get_num_of_path_per_dp_mst_connector(
-+ struct adapter_service *as);
-+
-+uint32_t dal_adapter_service_get_num_of_underlays(
-+ struct adapter_service *as);
-+
-+bool dal_adapter_service_get_encoder_cap_info(
-+ struct adapter_service *as,
-+ struct graphics_object_id id,
-+ struct graphics_object_encoder_cap_info *info);
-+
-+bool dal_adapter_service_is_mc_tuning_req(struct adapter_service *as);
-+
-+#endif /* __DAL_ADAPTER_SERVICE_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/adapter_service_types.h b/drivers/gpu/drm/amd/dal/include/adapter_service_types.h
-new file mode 100644
-index 0000000..fb47ef3
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/adapter_service_types.h
-@@ -0,0 +1,70 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_ADAPTER_SERVICE_TYPES_H__
-+#define __DAL_ADAPTER_SERVICE_TYPES_H__
-+
-+enum as_signal_type {
-+ AS_SIGNAL_TYPE_NONE = 0L, /* no signal */
-+ AS_SIGNAL_TYPE_DVI,
-+ AS_SIGNAL_TYPE_HDMI,
-+ AS_SIGNAL_TYPE_LVDS,
-+ AS_SIGNAL_TYPE_DISPLAY_PORT,
-+ AS_SIGNAL_TYPE_GPU_PLL,
-+ AS_SIGNAL_TYPE_UNKNOWN
-+};
-+
-+/*
-+ * Struct used for algorithm of Bandwidth tuning parameters
-+ * the sequence of the fields is binded with runtime parameter.
-+ */
-+union bandwidth_tuning_params {
-+ struct bandwidth_tuning_params_struct {
-+ uint32_t read_delay_stutter_off_usec;
-+ uint32_t ignore_hblank_time;/*bool*/
-+ uint32_t extra_reordering_latency_usec;
-+ uint32_t extra_mc_latency_usec;
-+ uint32_t data_return_bandwidth_eff;/*in %*/
-+ uint32_t dmif_request_bandwidth_eff;/*in %*/
-+ uint32_t sclock_latency_multiplier;/*in unit of 0.01*/
-+ uint32_t mclock_latency_multiplier;/*in unit of 0.01*/
-+ uint32_t fix_latency_multiplier;/*in unit of 0.01*/
-+ /*in unit represent in watermark*/
-+ uint32_t use_urgency_watermark_offset;
-+ } tuning_info;
-+ uint32_t arr_info[sizeof(struct bandwidth_tuning_params_struct)
-+ / sizeof(uint32_t)];
-+};
-+
-+union audio_support {
-+ struct {
-+ uint32_t DP_AUDIO:1;
-+ uint32_t HDMI_AUDIO_ON_DONGLE:1;
-+ uint32_t HDMI_AUDIO_NATIVE:1;
-+ } bits;
-+ uint32_t raw;
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/adjustment_interface.h b/drivers/gpu/drm/amd/dal/include/adjustment_interface.h
-new file mode 100644
-index 0000000..64a9f9f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/adjustment_interface.h
-@@ -0,0 +1,230 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_ADJUSTMENT_INTERFACE_H__
-+#define __DAL_ADJUSTMENT_INTERFACE_H__
-+
-+#include "include/display_service_types.h"
-+#include "include/adjustment_types.h"
-+#include "include/overlay_types.h"
-+#include "include/display_path_interface.h"
-+
-+struct ds_underscan_desc;
-+struct adj_container;
-+struct info_frame;
-+struct ds_dispatch;
-+struct hw_adjustment_set;
-+struct path_mode;
-+struct hw_path_mode;
-+
-+enum build_path_set_reason;
-+
-+bool dal_ds_dispatch_is_adjustment_supported(
-+ struct ds_dispatch *ds,
-+ uint32_t display_index,
-+ enum adjustment_id adjust_id);
-+
-+enum ds_return dal_ds_dispatch_get_type(
-+ struct ds_dispatch *adj,
-+ enum adjustment_id adjust_id,
-+ enum adjustment_data_type *type);
-+
-+enum ds_return dal_ds_dispatch_get_property(
-+ struct ds_dispatch *adj,
-+ uint32_t display_index,
-+ enum adjustment_id adjust_id,
-+ union adjustment_property *property);
-+
-+enum ds_return dal_ds_dispatch_set_adjustment(
-+ struct ds_dispatch *ds,
-+ const uint32_t display_index,
-+ enum adjustment_id adjust_id,
-+ int32_t value);
-+
-+enum ds_return dal_ds_dispatch_get_adjustment_current_value(
-+ struct ds_dispatch *ds,
-+ struct adj_container *container,
-+ struct adjustment_info *info,
-+ enum adjustment_id id,
-+ bool fall_back_to_default);
-+
-+enum ds_return dal_ds_dispatch_get_adjustment_value(
-+ struct ds_dispatch *ds,
-+ struct display_path *disp_path,
-+ enum adjustment_id adj_id,
-+ bool fall_back_to_default,
-+ int32_t *value);
-+
-+const struct raw_gamma_ramp *dal_ds_dispatch_get_current_gamma(
-+ struct ds_dispatch *ds,
-+ uint32_t display_index,
-+ enum adjustment_id adjust_id);
-+
-+const struct raw_gamma_ramp *dal_ds_dispatch_get_default_gamma(
-+ struct ds_dispatch *ds,
-+ uint32_t display_index,
-+ enum adjustment_id adjust_id);
-+
-+enum ds_return dal_ds_dispatch_set_current_gamma(
-+ struct ds_dispatch *ds,
-+ uint32_t display_index,
-+ enum adjustment_id adjust_id,
-+ const struct raw_gamma_ramp *gamma);
-+
-+enum ds_return dal_ds_dispatch_set_gamma(
-+ struct ds_dispatch *ds,
-+ uint32_t display_index,
-+ enum adjustment_id adjust_id,
-+ const struct raw_gamma_ramp *gamma);
-+
-+bool dal_ds_dispatch_get_underscan_info(
-+ struct ds_dispatch *ds,
-+ uint32_t display_index,
-+ struct ds_underscan_info *info);
-+
-+bool dal_ds_dispatch_get_underscan_mode(
-+ struct ds_dispatch *ds,
-+ uint32_t display_index,
-+ struct ds_underscan_desc *desc);
-+
-+bool dal_ds_dispatch_set_underscan_mode(
-+ struct ds_dispatch *ds,
-+ uint32_t display_index,
-+ struct ds_underscan_desc *desc);
-+
-+bool dal_ds_dispatch_setup_overlay(
-+ struct ds_dispatch *adj,
-+ uint32_t display_index,
-+ struct overlay_data *data);
-+
-+struct adj_container *dal_ds_dispatch_get_adj_container_for_path(
-+ const struct ds_dispatch *ds,
-+ uint32_t display_index);
-+
-+void dal_ds_dispatch_set_applicable_adj(
-+ struct ds_dispatch *adj,
-+ uint32_t display_index,
-+ const struct adj_container *applicable);
-+
-+enum ds_return dal_ds_dispatch_set_color_gamut(
-+ struct ds_dispatch *adj,
-+ uint32_t display_index,
-+ const struct ds_set_gamut_data *data);
-+
-+enum ds_return dal_ds_dispatch_get_color_gamut(
-+ struct ds_dispatch *adj,
-+ uint32_t display_index,
-+ const struct ds_gamut_reference_data *ref,
-+ struct ds_get_gamut_data *data);
-+
-+enum ds_return dal_ds_dispatch_get_color_gamut_info(
-+ struct ds_dispatch *adj,
-+ uint32_t display_index,
-+ const struct ds_gamut_reference_data *ref,
-+ struct ds_gamut_info *data);
-+
-+enum ds_return dal_ds_dispatch_get_regamma_lut(
-+ struct ds_dispatch *adj,
-+ uint32_t display_index,
-+ struct ds_regamma_lut *data);
-+
-+enum ds_return dal_ds_dispatch_set_regamma_lut(
-+ struct ds_dispatch *adj,
-+ uint32_t display_index,
-+ struct ds_regamma_lut *data);
-+
-+enum ds_return dal_ds_dispatch_set_info_packets(
-+ struct ds_dispatch *adj,
-+ uint32_t display_index,
-+ const struct info_frame *info_frames);
-+
-+enum ds_return dal_ds_dispatch_get_info_packets(
-+ struct ds_dispatch *adj,
-+ uint32_t display_index,
-+ struct info_frame *info_frames);
-+
-+bool dal_ds_dispatch_initialize_adjustment(struct ds_dispatch *ds);
-+
-+void dal_ds_dispatch_cleanup_adjustment(struct ds_dispatch *ds);
-+
-+bool dal_ds_dispatch_build_post_set_mode_adj(
-+ struct ds_dispatch *ds,
-+ const struct path_mode *mode,
-+ struct display_path *display_path,
-+ struct hw_adjustment_set *set);
-+
-+bool dal_ds_dispatch_build_color_control_adj(
-+ struct ds_dispatch *ds,
-+ const struct path_mode *mode,
-+ struct display_path *display_path,
-+ struct hw_adjustment_set *set);
-+
-+bool dal_ds_dispatch_build_include_adj(
-+ struct ds_dispatch *ds,
-+ const struct path_mode *mode,
-+ struct display_path *display_path,
-+ struct hw_path_mode *hw_mode,
-+ struct hw_adjustment_set *set);
-+
-+bool dal_ds_dispatch_apply_scaling(
-+ struct ds_dispatch *ds,
-+ const struct path_mode *mode,
-+ struct adj_container *adj_container,
-+ enum build_path_set_reason reason,
-+ struct hw_path_mode *hw_mode);
-+
-+void dal_ds_dispatch_update_adj_container_for_path_with_mode_info(
-+ struct ds_dispatch *ds,
-+ struct display_path *display_path,
-+ const struct path_mode *path_mode);
-+
-+enum ds_return dal_ds_dispatch_get_adjustment_info(
-+ struct ds_dispatch *ds,
-+ uint32_t display_index,
-+ enum adjustment_id adjust_id,
-+ struct adjustment_info *adj_info);
-+
-+bool dal_ds_dispatch_include_adjustment(
-+ struct ds_dispatch *ds,
-+ struct display_path *disp_path,
-+ struct ds_adj_id_value adj,
-+ struct hw_adjustment_set *set);
-+
-+enum ds_return dal_ds_dispatch_set_gamma_adjustment(
-+ struct ds_dispatch *ds,
-+ uint32_t display_index,
-+ enum adjustment_id ad_id,
-+ const struct raw_gamma_ramp *gamma);
-+
-+void dal_ds_dispatch_update_adj_container_for_path_with_color_space(
-+ struct ds_dispatch *ds,
-+ uint32_t display_index,
-+ enum ds_color_space color_space);
-+
-+void dal_ds_dispatch_setup_default_regamma(
-+ struct ds_dispatch *ds,
-+ struct ds_regamma_lut *regamma);
-+
-+#endif /* __DAL_ADJUSTMENT_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/adjustment_types.h b/drivers/gpu/drm/amd/dal/include/adjustment_types.h
-new file mode 100644
-index 0000000..f6c0d61
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/adjustment_types.h
-@@ -0,0 +1,420 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_ADJUSTMENT_TYPES_H__
-+#define __DAL_ADJUSTMENT_TYPES_H__
-+
-+#include "dal_services.h"
-+
-+/* make sure to update this when updating adj_global_info_array */
-+#define CURRENT_ADJUSTMENT_NUM 12
-+#define MAX_ADJUSTMENT_NUM (ADJ_ID_END - ADJ_ID_BEGIN)
-+#define REGAMMA_VALUE 256
-+#define REGAMMA_RANGE (REGAMMA_VALUE*3)
-+#define ADJUST_DIVIDER 100
-+#define GAMUT_DIVIDER 10000
-+
-+
-+enum adjustment_id {
-+
-+ /*this useful type when i need to indicate unknown adjustment and code
-+ look if not the specific type*/
-+ ADJ_ID_INVALID,
-+
-+ ADJ_ID_CONTRAST,
-+ ADJ_ID_BRIGHTNESS,
-+ ADJ_ID_HUE,
-+ ADJ_ID_SATURATION,
-+ ADJ_ID_GAMMA_RAMP,
-+ ADJ_ID_GAMMA_RAMP_REGAMMA_UPDATE,
-+ ADJ_ID_TEMPERATURE,
-+ ADJ_ID_NOMINAL_RANGE_RGB_LIMITED,
-+
-+ ADJ_ID_LP_FILTER_DEFLICKER,
-+ ADJ_ID_HP_FILTER_DEFLICKER,
-+ ADJ_ID_SHARPNESS_GAIN, /*0 - 10*/
-+
-+ ADJ_ID_REDUCED_BLANKING,
-+ ADJ_ID_COHERENT,
-+ ADJ_ID_MULTIMEDIA_PASS_THROUGH,
-+
-+ ADJ_ID_VERTICAL_POSITION,
-+ ADJ_ID_HORIZONTA_LPOSITION,
-+ ADJ_ID_VERTICAL_SIZE,
-+ ADJ_ID_HORIZONTAL_SIZE,
-+ ADJ_ID_VERTICAL_SYNC,
-+ ADJ_ID_HORIZONTAL_SYNC,
-+ ADJ_ID_OVERSCAN,
-+ ADJ_ID_COMPOSITE_SYNC,
-+
-+ ADJ_ID_BIT_DEPTH_REDUCTION,/*CWDDEDI_DISPLAY_ADJINFOTYPE_BITVECTOR*/
-+ ADJ_ID_UNDERSCAN,/*CWDDEDI_DISPLAY_ADJINFOTYPE_RANGE*/
-+ ADJ_ID_UNDERSCAN_TYPE,/*CWDDEDI_DISPLAY_ADJINFOTYPE_RANGE*/
-+ ADJ_ID_TEMPERATURE_SOURCE,/*CWDDEDI_DISPLAY_ADJINFOTYPE_BITVECTOR*/
-+
-+ ADJ_ID_OVERLAY_BRIGHTNESS,
-+ ADJ_ID_OVERLAY_CONTRAST,
-+ ADJ_ID_OVERLAY_SATURATION,
-+ ADJ_ID_OVERLAY_HUE,
-+ ADJ_ID_OVERLAY_GAMMA,
-+ ADJ_ID_OVERLAY_ALPHA,
-+ ADJ_ID_OVERLAY_ALPHA_PER_PIX,
-+ ADJ_ID_OVERLAY_INV_GAMMA,
-+ ADJ_ID_OVERLAY_TEMPERATURE,/*done ,but code is commented*/
-+ ADJ_ID_OVERLAY_NOMINAL_RANGE_RGB_LIMITED,
-+
-+
-+ ADJ_ID_UNDERSCAN_TV_INTERNAL,/*internal usage only for HDMI*/
-+ /*custom TV modes*/
-+ ADJ_ID_DRIVER_REQUESTED_GAMMA,/*used to get current gamma*/
-+ ADJ_ID_GAMUT_SOURCE_GRPH,/*logical adjustment visible for DS and CDB*/
-+ ADJ_ID_GAMUT_SOURCE_OVL,/*logical adjustment visible for DS and CDB*/
-+ ADJ_ID_GAMUT_DESTINATION,/*logical adjustment visible for DS and CDB*/
-+ ADJ_ID_REGAMMA,/*logical adjustment visible for DS and CDB*/
-+ ADJ_ID_ITC_ENABLE,/*ITC flag enable by default*/
-+ ADJ_ID_CNC_CONTENT,/*display image content*/
-+ /*internal adjustment, in order to provide backward compatibility
-+ gamut with color temperature*/
-+
-+ /* Backlight Adjustment Group*/
-+ ADJ_ID_BACKLIGHT,
-+ ADJ_ID_BACKLIGHT_OPTIMIZATION,
-+
-+ /* flag the first and last*/
-+ ADJ_ID_BEGIN = ADJ_ID_CONTRAST,
-+ ADJ_ID_END = ADJ_ID_BACKLIGHT_OPTIMIZATION,
-+};
-+
-+enum adjustment_data_type {
-+ ADJ_RANGED,
-+ ADJ_BITVECTOR,
-+ ADJ_LUT /* not handled currently */
-+};
-+
-+union adjustment_property {
-+ uint32_t u32all;
-+ struct {
-+ /*per mode adjustment*/
-+ uint32_t SAVED_WITHMODE:1;
-+ /*per edid adjustment*/
-+ uint32_t SAVED_WITHEDID:1;
-+ /*adjustment not visible to HWSS*/
-+ uint32_t CALCULATE:1;
-+ /*explisit adjustment applied by HWSS*/
-+ uint32_t INC_IN_SET_MODE:1;
-+ /*adjustment requires set mode to be applied*/
-+ uint32_t SETMODE_REQ:1;
-+ /*adjustment is applied at the end of set mode*/
-+ uint32_t POST_SET:1;
-+/*when adjustment is applied its value should be stored
-+in place and not wait for flush call*/
-+ uint32_t SAVE_IN_PLACE:1;
-+ /*adjustment is always apply*/
-+ uint32_t FORCE_SET:1;
-+ /*this adjustment is specific to individual display path.*/
-+ uint32_t SAVED_WITH_DISPLAY_IDX:1;
-+ uint32_t RESERVED_23:23;
-+ } bits;
-+};
-+
-+enum adjustment_state {
-+ ADJUSTMENT_STATE_INVALID,
-+ ADJUSTMENT_STATE_VALID,
-+ ADJUSTMENT_STATE_REQUESTED,
-+ ADJUSTMENT_STATE_COMMITTED_TO_HW,
-+};
-+
-+/* AdjustmentInfo structure - it keeps either ranged data or discrete*/
-+struct adjustment_info {
-+ enum adjustment_data_type adj_data_type;
-+ union adjustment_property adj_prop;
-+ enum adjustment_state adj_state;
-+ enum adjustment_id adj_id;
-+
-+ union data {
-+ struct ranged {
-+ int32_t min;
-+ int32_t max;
-+ int32_t def;
-+ int32_t step;
-+ int32_t cur;
-+ } ranged;
-+ struct bit_vector {
-+ int32_t system_supported;
-+ int32_t current_supported;
-+ int32_t default_val;
-+ } bit_vector;
-+ } adj_data;
-+};
-+
-+/* adjustment category
-+this should be a MASK struct with the bitfileds!!!
-+since it could be crt and cv and dfp!!!
-+the only fit is for overlay!!!*/
-+enum adjustment_category {
-+ CAT_ALL,
-+ CAT_CRT,
-+ CAT_DFP,
-+ CAT_LCD,
-+ CAT_OVERLAY,
-+ CAT_INVALID
-+};
-+
-+enum raw_gamma_ramp_type {
-+ GAMMA_RAMP_TYPE_UNINITIALIZED,
-+ GAMMA_RAMP_TYPE_DEFAULT,
-+ GAMMA_RAMP_TYPE_RGB256,
-+ GAMMA_RAMP_TYPE_FIXED_POINT
-+};
-+
-+struct raw_gamma_ramp_rgb {
-+ uint32_t red;
-+ uint32_t green;
-+ uint32_t blue;
-+};
-+
-+#define NUM_OF_RAW_GAMMA_RAMP_RGB_256 256
-+struct raw_gamma_ramp {
-+ enum raw_gamma_ramp_type type;
-+ struct raw_gamma_ramp_rgb rgb_256[NUM_OF_RAW_GAMMA_RAMP_RGB_256];
-+ uint32_t size;
-+};
-+
-+struct ds_underscan_info {
-+ uint32_t default_width;
-+ uint32_t default_height;
-+ uint32_t max_width;
-+ uint32_t max_height;
-+ uint32_t min_width;
-+ uint32_t min_height;
-+ uint32_t h_step;
-+ uint32_t v_step;
-+ uint32_t default_x_pos;
-+ uint32_t default_y_pos;
-+};
-+
-+struct ds_overscan {
-+ uint32_t left;
-+ uint32_t right;
-+ uint32_t top;
-+ uint32_t bottom;
-+};
-+
-+enum ds_color_space {
-+ DS_COLOR_SPACE_UNKNOWN = 0,
-+ DS_COLOR_SPACE_SRGB_FULLRANGE = 1,
-+ DS_COLOR_SPACE_SRGB_LIMITEDRANGE,
-+ DS_COLOR_SPACE_YPBPR601,
-+ DS_COLOR_SPACE_YPBPR709,
-+ DS_COLOR_SPACE_YCBCR601,
-+ DS_COLOR_SPACE_YCBCR709,
-+ DS_COLOR_SPACE_NMVPU_SUPERAA,
-+ DS_COLOR_SPACE_YCBCR601_YONLY,
-+ DS_COLOR_SPACE_YCBCR709_YONLY/*same as YCbCr, but Y in Full range*/
-+};
-+
-+enum ds_underscan_options {
-+ DS_UNDERSCAN_OPTION_DEFAULT = 0,
-+ DS_UNDERSCAN_OPTION_USECEA861D
-+};
-+
-+enum dpms_state {
-+ DPMS_NONE = 0,
-+ DPMS_ON,
-+ DPMS_OFF,
-+};
-+
-+enum ds_gamut_reference {
-+ DS_GAMUT_REFERENCE_DESTINATION = 0,
-+ DS_GAMUT_REFERENCE_SOURCE,
-+};
-+
-+enum ds_gamut_content {
-+ DS_GAMUT_CONTENT_GRAPHICS = 0,
-+ DS_GAMUT_CONTENT_VIDEO,
-+};
-+
-+struct ds_gamut_reference_data {
-+ enum ds_gamut_reference gamut_ref;
-+ enum ds_gamut_content gamut_content;
-+};
-+
-+union ds_custom_gamut_type {
-+ uint32_t u32all;
-+ struct {
-+ uint32_t CUSTOM_WHITE_POINT:1;
-+ uint32_t CUSTOM_GAMUT_SPACE:1;
-+ uint32_t reserved:30;
-+ } bits;
-+};
-+
-+union ds_gamut_spaces {
-+ uint32_t u32all;
-+ struct {
-+ uint32_t GAMUT_SPACE_CCIR709:1;
-+ uint32_t GAMUT_SPACE_CCIR601:1;
-+ uint32_t GAMUT_SPACE_ADOBERGB:1;
-+ uint32_t GAMUT_SPACE_CIERGB:1;
-+ uint32_t GAMUT_SPACE_CUSTOM:1;
-+ uint32_t reserved:27;
-+ } bits;
-+};
-+
-+union ds_gamut_white_point {
-+ uint32_t u32all;
-+ struct {
-+ uint32_t GAMUT_WHITE_POINT_5000:1;
-+ uint32_t GAMUT_WHITE_POINT_6500:1;
-+ uint32_t GAMUT_WHITE_POINT_7500:1;
-+ uint32_t GAMUT_WHITE_POINT_9300:1;
-+ uint32_t GAMUT_WHITE_POINT_CUSTOM:1;
-+ uint32_t reserved:27;
-+ } bits;
-+};
-+
-+struct ds_gamut_space_coordinates {
-+ int32_t red_x;
-+ int32_t red_y;
-+ int32_t green_x;
-+ int32_t green_y;
-+ int32_t blue_x;
-+ int32_t blue_y;
-+
-+};
-+
-+struct ds_white_point_coordinates {
-+ int32_t white_x;
-+ int32_t white_y;
-+};
-+
-+struct ds_gamut_data {
-+ union ds_custom_gamut_type feature;
-+ union {
-+ uint32_t predefined;
-+ struct ds_white_point_coordinates custom;
-+
-+ } white_point;
-+
-+ union {
-+ uint32_t predefined;
-+ struct ds_gamut_space_coordinates custom;
-+
-+ } gamut;
-+};
-+
-+struct ds_set_gamut_data {
-+ struct ds_gamut_reference_data ref;
-+ struct ds_gamut_data gamut;
-+
-+};
-+
-+struct ds_get_gamut_data {
-+ struct ds_gamut_data gamut;
-+};
-+
-+struct ds_gamut_info {
-+/*mask of supported predefined gamuts ,started from DI_GAMUT_SPACE_CCIR709 ...*/
-+ union ds_gamut_spaces gamut_space;
-+/*mask of supported predefined white points,started from DI_WHITE_POINT_5000K */
-+ union ds_gamut_white_point white_point;
-+
-+};
-+
-+union ds_regamma_flags {
-+ uint32_t u32all;
-+ struct {
-+ /*custom/user gamam array is in use*/
-+ uint32_t GAMMA_RAMP_ARRAY:1;
-+ /*gamma from edid is in use*/
-+ uint32_t GAMMA_FROM_EDID:1;
-+ /*gamma from edid is in use , but only for Display Id 1.2*/
-+ uint32_t GAMMA_FROM_EDID_EX:1;
-+ /*user custom gamma is in use*/
-+ uint32_t GAMMA_FROM_USER:1;
-+ /*coeff. A0-A3 from user is in use*/
-+ uint32_t COEFF_FROM_USER:1;
-+ /*coeff. A0-A3 from edid is in use only for Display Id 1.2*/
-+ uint32_t COEFF_FROM_EDID:1;
-+ /*which ROM to choose for graphics*/
-+ uint32_t GRAPHICS_DEGAMMA_SRGB:1;
-+ /*which ROM to choose for video overlay*/
-+ uint32_t OVERLAY_DEGAMMA_SRGB:1;
-+ /*apply degamma removal in driver*/
-+ uint32_t APPLY_DEGAMMA:1;
-+
-+ uint32_t reserved:23;
-+ } bits;
-+};
-+
-+struct ds_regamma_ramp {
-+ uint16_t gamma[256 * 3]; /* gamma ramp packed as RGB */
-+
-+};
-+
-+struct ds_regamma_coefficients_ex {
-+ int32_t gamma[3];/*2400 use divider 1 000*/
-+ int32_t coeff_a0[3];/*31308 divider 10 000 000,0-red, 1-green, 2-blue*/
-+ int32_t coeff_a1[3];/*12920 use divider 1 000*/
-+ int32_t coeff_a2[3];/*55 use divider 1 000*/
-+ int32_t coeff_a3[3];/*55 use divider 1 000*/
-+};
-+
-+struct ds_regamma_lut {
-+ union ds_regamma_flags flags;
-+ union {
-+ struct ds_regamma_ramp gamma;
-+ struct ds_regamma_coefficients_ex coeff;
-+ };
-+};
-+
-+enum ds_backlight_optimization {
-+ DS_BACKLIGHT_OPTIMIZATION_DISABLE = 0,
-+ DS_BACKLIGHT_OPTIMIZATION_DESKTOP,
-+ DS_BACKLIGHT_OPTIMIZATION_DYNAMIC,
-+ DS_BACKLIGHT_OPTIMIZATION_DIMMED
-+};
-+
-+struct ds_adj_id_value {
-+ enum adjustment_id adj_id;
-+ enum adjustment_data_type adj_type;
-+ union adjustment_property adj_prop;
-+ int32_t value;
-+};
-+
-+struct gamut_data {
-+ union ds_custom_gamut_type option;
-+ union {
-+ union ds_gamut_white_point predefined;
-+ struct ds_white_point_coordinates custom;
-+
-+ } white_point;
-+
-+ union {
-+ union ds_gamut_spaces predefined;
-+ struct ds_gamut_space_coordinates custom;
-+
-+ } gamut;
-+};
-+#endif /* __DAL_ADJUSTMENT_TYPES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/asic_capability_interface.h b/drivers/gpu/drm/amd/dal/include/asic_capability_interface.h
-new file mode 100644
-index 0000000..bdeaaf9
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/asic_capability_interface.h
-@@ -0,0 +1,58 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of enc software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and enc permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_ASIC_CAPABILITY_INTERFACE_H__
-+#define __DAL_ASIC_CAPABILITY_INTERFACE_H__
-+
-+/* Include */
-+#include "include/asic_capability_types.h"
-+
-+/* Forward declaration */
-+struct hw_asic_id;
-+
-+
-+/* ASIC capability */
-+struct asic_capability {
-+ struct dc_context *ctx;
-+ struct asic_caps caps;
-+ struct asic_stereo_3d_caps stereo_3d_caps;
-+ struct asic_bugs bugs;
-+ struct dal_asic_runtime_flags runtime_flags;
-+ uint32_t data[ASIC_DATA_MAX_NUMBER];
-+};
-+
-+
-+/**
-+ * Interfaces
-+ */
-+
-+/* Create and initialize ASIC capability */
-+struct asic_capability *dal_asic_capability_create(struct hw_asic_id *init,
-+ struct dc_context *ctx);
-+
-+/* Destroy ASIC capability and free memory space */
-+void dal_asic_capability_destroy(struct asic_capability **cap);
-+
-+#endif /* __DAL_ASIC_CAPABILITY_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/asic_capability_types.h b/drivers/gpu/drm/amd/dal/include/asic_capability_types.h
-new file mode 100644
-index 0000000..1cb9776
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/asic_capability_types.h
-@@ -0,0 +1,134 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef __DAL_ASIC_CAPABILITY_TYPES_H__
-+#define __DAL_ASIC_CAPABILITY_TYPES_H__
-+
-+/*
-+ * ASIC Capabilities
-+ */
-+struct asic_caps {
-+ bool CONSUMER_SINGLE_SELECTED_TIMING:1;
-+ bool UNDERSCAN_ADJUST:1;
-+ bool DELTA_SIGMA_SUPPORT:1;
-+ bool PANEL_SELF_REFRESH_SUPPORTED:1;
-+ bool IS_FUSION:1;
-+ bool DP_MST_SUPPORTED:1;
-+ bool UNDERSCAN_FOR_HDMI_ONLY:1;
-+ bool DVI_CLOCK_SHARE_CAPABILITY:1;
-+ bool SUPPORT_CEA861E_FINAL:1;
-+ bool MIRABILIS_SUPPORTED:1;
-+ bool MIRABILIS_ENABLED_BY_DEFAULT:1;
-+ bool DEVICE_TAG_REMAP_SUPPORTED:1;
-+ bool HEADLESS_NO_OPM_SUPPORTED:1;
-+ bool WIRELESS_LIMIT_TO_720P:1;
-+ bool WIRELESS_FULL_TIMING_ADJUSTMENT:1;
-+ bool WIRELESS_TIMING_ADJUSTMENT:1;
-+ bool WIRELESS_COMPRESSED_AUDIO:1;
-+ bool VCE_SUPPORTED:1;
-+ bool HPD_CHECK_FOR_EDID:1;
-+ bool NO_VCC_OFF_HPD_POLLING:1;
-+ bool NEED_MC_TUNING:1;
-+ bool SKIP_PSR_WAIT_FOR_PLL_LOCK_BIT:1;
-+ bool DFSBYPASS_DYNAMIC_SUPPORT:1;
-+ bool SUPPORT_8BPP:1;
-+};
-+
-+
-+/*
-+ * ASIC Stereo 3D Caps
-+ */
-+struct asic_stereo_3d_caps {
-+ bool SUPPORTED:1;
-+ bool DISPLAY_BASED_ON_WS:1;
-+ bool HDMI_FRAME_PACK:1;
-+ bool INTERLACE_FRAME_PACK:1;
-+ bool DISPLAYPORT_FRAME_PACK:1;
-+ bool DISPLAYPORT_FRAME_ALT:1;
-+ bool INTERLEAVE:1;
-+};
-+
-+
-+/*
-+ * ASIC Bugs
-+ */
-+struct asic_bugs {
-+ bool MST_SYMBOL_MISALIGNMENT:1;
-+ bool PSR_2X_LANE_GANGING:1;
-+ bool LB_WA_IS_SUPPORTED:1;
-+ bool ROM_REGISTER_ACCESS:1;
-+ bool PSR_WA_OVERSCAN_CRC_ERROR:1;
-+};
-+
-+
-+/*
-+ * ASIC Data
-+ */
-+enum asic_data {
-+ ASIC_DATA_FIRST = 0,
-+ ASIC_DATA_CONTROLLERS_NUM = ASIC_DATA_FIRST,
-+ ASIC_DATA_FUNCTIONAL_CONTROLLERS_NUM,
-+ ASIC_DATA_DCE_VERSION,
-+ ASIC_DATA_DCE_VERSION_MINOR,
-+ ASIC_DATA_VRAM_TYPE,
-+ ASIC_DATA_VRAM_BITWIDTH,
-+ ASIC_DATA_FEATURE_FLAGS,
-+ ASIC_DATA_LINEBUFFER_NUM,
-+ ASIC_DATA_LINEBUFFER_SIZE,
-+ ASIC_DATA_DRAM_BANDWIDTH_EFFICIENCY,
-+ ASIC_DATA_MC_LATENCY,
-+ ASIC_DATA_MC_LATENCY_SLOW,
-+ ASIC_DATA_CLOCKSOURCES_NUM,
-+ ASIC_DATA_MEMORYTYPE_MULTIPLIER,
-+ ASIC_DATA_STUTTERMODE,
-+ ASIC_DATA_PATH_NUM_PER_DPMST_CONNECTOR,
-+ ASIC_DATA_MAX_COFUNC_NONDP_DISPLAYS,
-+ ASIC_DATA_REVISION_ID,
-+ ASIC_DATA_MAX_UNDERSCAN_PERCENTAGE,
-+ ASIC_DATA_VIEWPORT_PIXEL_GRANULARITY,
-+ ASIC_DATA_DIGFE_NUM,
-+ ASIC_DATA_SUPPORTED_HDMI_CONNECTION_NUM,
-+ ASIC_DATA_MIN_DISPCLK_FOR_UNDERSCAN,
-+ ASIC_DATA_NUM_OF_VIDEO_PLANES,
-+ ASIC_DATA_DEFAULT_I2C_SPEED_IN_KHZ,
-+ ASIC_DATA_MAX_NUMBER /* end of enum */
-+};
-+
-+
-+/*
-+ * ASIC Feature Flags
-+ */
-+struct asic_feature_flags {
-+ union {
-+ uint32_t raw;
-+ struct {
-+ uint32_t LEGACY_CLIENT:1;
-+ uint32_t PACKED_PIXEL_FORMAT:1;
-+ uint32_t WORKSTATION_STEREO:1;
-+ uint32_t WORKSTATION:1;
-+ } bits;
-+ };
-+};
-+
-+#endif /* __DAL_ASIC_CAPABILITY_TYPES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/audio_interface.h b/drivers/gpu/drm/amd/dal/include/audio_interface.h
-new file mode 100644
-index 0000000..bf21762
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/audio_interface.h
-@@ -0,0 +1,184 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_AUDIO_INTERFACE_H__
-+#define __DAL_AUDIO_INTERFACE_H__
-+
-+#include "audio_types.h"
-+#include "adapter_service_interface.h"
-+#include "signal_types.h"
-+#include "link_service_types.h"
-+
-+/* forward declaration */
-+struct audio;
-+struct dal_adapter_service;
-+
-+/***** audio initialization data *****/
-+/*
-+ * by audio, it means audio endpoint id. ASIC may have many endpoints.
-+ * upper sw layer will create one audio object instance for each endpoints.
-+ * ASIC support internal audio only. So enum number is used to differ
-+ * each endpoint
-+ */
-+struct audio_init_data {
-+ struct adapter_service *as;
-+ struct graphics_object_id audio_stream_id;
-+ struct dc_context *ctx;
-+};
-+
-+enum audio_result {
-+ AUDIO_RESULT_OK,
-+ AUDIO_RESULT_ERROR,
-+};
-+
-+/****** audio object create, destroy ******/
-+struct audio *dal_audio_create(
-+ const struct audio_init_data *init_data);
-+
-+void dal_audio_destroy(
-+ struct audio **audio);
-+
-+/****** graphics object interface ******/
-+const struct graphics_object_id dal_audio_get_graphics_object_id(
-+ const struct audio *audio);
-+
-+/* Enumerate Graphics Object supported Input/Output Signal Types */
-+uint32_t dal_audio_enumerate_input_signals(
-+ struct audio *audio);
-+
-+uint32_t dal_audio_enumerate_output_signals(
-+ struct audio *audio);
-+
-+/* Check if signal supported by GraphicsObject */
-+bool dal_audio_is_input_signal_supported(
-+ struct audio *audio,
-+ enum signal_type signal);
-+
-+bool dal_audio_is_output_signal_supported(
-+ struct audio *audio,
-+ enum signal_type signal);
-+
-+
-+/***** programming interface *****/
-+
-+/* perform power up sequence (boot up, resume, recovery) */
-+enum audio_result dal_audio_power_up(
-+ struct audio *audio);
-+
-+/* perform power down (shut down, stand by) */
-+enum audio_result dal_audio_power_down(
-+ struct audio *audio);
-+
-+/* setup audio */
-+enum audio_result dal_audio_setup(
-+ struct audio *audio,
-+ struct audio_output *output,
-+ struct audio_info *info);
-+
-+/* enable audio */
-+enum audio_result dal_audio_enable_output(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal);
-+
-+/* disable audio */
-+enum audio_result dal_audio_disable_output(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal);
-+
-+/* enable azalia audio endpoint */
-+enum audio_result dal_audio_enable_azalia_audio_jack_presence(
-+ struct audio *audio,
-+ enum engine_id engine_id);
-+
-+/* disable azalia audio endpoint */
-+enum audio_result dal_audio_disable_azalia_audio_jack_presence(
-+ struct audio *audio,
-+ enum engine_id engine_id);
-+
-+/* unmute audio */
-+enum audio_result dal_audio_unmute(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal);
-+
-+/* mute audio */
-+enum audio_result dal_audio_mute(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal);
-+
-+
-+/***** information interface *****/
-+
-+struct audio_feature_support dal_audio_get_supported_features(
-+ struct audio *audio);
-+
-+/* get audio bandwidth information */
-+void dal_audio_check_audio_bandwidth(
-+ struct audio *audio,
-+ const struct audio_crtc_info *info,
-+ uint32_t channel_count,
-+ enum signal_type signal,
-+ union audio_sample_rates *sample_rates);
-+
-+/* Enable multi channel split */
-+void dal_audio_enable_channel_splitting_mapping(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ const struct audio_channel_associate_info *audio_mapping,
-+ bool enable);
-+
-+/* get current multi channel split. */
-+enum audio_result dal_audio_get_channel_splitting_mapping(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ struct audio_channel_associate_info *audio_mapping);
-+
-+/* set payload value for the unsolicited response */
-+void dal_audio_set_unsolicited_response_payload(
-+ struct audio *audio,
-+ enum audio_payload payload);
-+
-+/*Assign GTC group and enable GTC value embedding*/
-+void dal_audio_enable_gtc_embedding_with_group(
-+ struct audio *audio,
-+ uint32_t group_num,
-+ uint32_t audio_latency);
-+
-+/* Disable GTC value embedding */
-+void dal_audio_disable_gtc_embedding(
-+ struct audio *audio);
-+
-+/* Update audio wall clock source */
-+void dal_audio_setup_audio_wall_dto(
-+ struct audio *audio,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_pll_info *pll_info);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/audio_types.h b/drivers/gpu/drm/amd/dal/include/audio_types.h
-new file mode 100644
-index 0000000..e9c2ab3
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/audio_types.h
-@@ -0,0 +1,275 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __AUDIO_TYPES_H__
-+#define __AUDIO_TYPES_H__
-+
-+#include "grph_object_defs.h"
-+#include "signal_types.h"
-+
-+#define AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS 20
-+#define MAX_HW_AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS 18
-+#define MULTI_CHANNEL_SPLIT_NO_ASSO_INFO 0xFFFFFFFF
-+
-+
-+struct audio_pll_hw_settings {
-+ uint32_t feed_back_divider;
-+ uint32_t step_size_integer;
-+ uint32_t step_size_fraction;
-+ uint32_t step_range;
-+};
-+
-+struct audio_clock_info {
-+ /* pixel clock frequency*/
-+ uint32_t pixel_clock_in_10khz;
-+ /* N - 32KHz audio */
-+ uint32_t n_32khz;
-+ /* CTS - 32KHz audio*/
-+ uint32_t cts_32khz;
-+ uint32_t n_44khz;
-+ uint32_t cts_44khz;
-+ uint32_t n_48khz;
-+ uint32_t cts_48khz;
-+};
-+
-+struct azalia_clock_info {
-+ uint32_t pixel_clock_in_10khz;
-+ uint32_t audio_dto_phase;
-+ uint32_t audio_dto_module;
-+ uint32_t audio_dto_wall_clock_ratio;
-+};
-+
-+enum audio_dto_source {
-+ DTO_SOURCE_UNKNOWN = 0,
-+ DTO_SOURCE_ID0,
-+ DTO_SOURCE_ID1,
-+ DTO_SOURCE_ID2,
-+ DTO_SOURCE_ID3,
-+ DTO_SOURCE_ID4,
-+ DTO_SOURCE_ID5
-+};
-+
-+union audio_sample_rates {
-+ struct sample_rates {
-+ uint8_t RATE_32:1;
-+ uint8_t RATE_44_1:1;
-+ uint8_t RATE_48:1;
-+ uint8_t RATE_88_2:1;
-+ uint8_t RATE_96:1;
-+ uint8_t RATE_176_4:1;
-+ uint8_t RATE_192:1;
-+ } rate;
-+
-+ uint8_t all;
-+};
-+
-+enum audio_format_code {
-+ AUDIO_FORMAT_CODE_FIRST = 1,
-+ AUDIO_FORMAT_CODE_LINEARPCM = AUDIO_FORMAT_CODE_FIRST,
-+
-+ AUDIO_FORMAT_CODE_AC3,
-+ /*Layers 1 & 2 */
-+ AUDIO_FORMAT_CODE_MPEG1,
-+ /*MPEG1 Layer 3 */
-+ AUDIO_FORMAT_CODE_MP3,
-+ /*multichannel */
-+ AUDIO_FORMAT_CODE_MPEG2,
-+ AUDIO_FORMAT_CODE_AAC,
-+ AUDIO_FORMAT_CODE_DTS,
-+ AUDIO_FORMAT_CODE_ATRAC,
-+ AUDIO_FORMAT_CODE_1BITAUDIO,
-+ AUDIO_FORMAT_CODE_DOLBYDIGITALPLUS,
-+ AUDIO_FORMAT_CODE_DTS_HD,
-+ AUDIO_FORMAT_CODE_MAT_MLP,
-+ AUDIO_FORMAT_CODE_DST,
-+ AUDIO_FORMAT_CODE_WMAPRO,
-+ AUDIO_FORMAT_CODE_LAST,
-+ AUDIO_FORMAT_CODE_COUNT =
-+ AUDIO_FORMAT_CODE_LAST - AUDIO_FORMAT_CODE_FIRST
-+};
-+
-+struct audio_mode {
-+ /* ucData[0] [6:3] */
-+ enum audio_format_code format_code;
-+ /* ucData[0] [2:0] */
-+ uint8_t channel_count;
-+ /* ucData[1] */
-+ union audio_sample_rates sample_rates;
-+ union {
-+ /* for LPCM */
-+ uint8_t sample_size;
-+ /* for Audio Formats 2-8 (Max bit rate divided by 8 kHz) */
-+ uint8_t max_bit_rate;
-+ /* for Audio Formats 9-15 */
-+ uint8_t vendor_specific;
-+ };
-+};
-+
-+struct audio_info_flags {
-+
-+ union {
-+
-+ struct audio_speaker_flags {
-+ uint32_t FL_FR:1;
-+ uint32_t LFE:1;
-+ uint32_t FC:1;
-+ uint32_t RL_RR:1;
-+ uint32_t RC:1;
-+ uint32_t FLC_FRC:1;
-+ uint32_t RLC_RRC:1;
-+ uint32_t SUPPORT_AI:1;
-+ } speaker_flags;
-+
-+ struct audio_speaker_info {
-+ uint32_t ALLSPEAKERS:7;
-+ uint32_t SUPPORT_AI:1;
-+ } info;
-+
-+ uint8_t all;
-+ };
-+};
-+
-+
-+/*struct audio_info_flags {
-+ struct audio_speaker_flags {
-+ uint32_t FL_FR:1;
-+ uint32_t LFE:1;
-+ uint32_t FC:1;
-+ uint32_t RL_RR:1;
-+ uint32_t RC:1;
-+ uint32_t FLC_FRC:1;
-+ uint32_t RLC_RRC:1;
-+ uint32_t SUPPORT_AI:1;
-+ };
-+
-+ struct audio_speaker_info {
-+ uint32_t ALLSPEAKERS:7;
-+ uint32_t SUPPORT_AI:1;
-+ };
-+
-+ union {
-+ struct audio_speaker_flags speaker_flags;
-+ struct audio_speaker_info info;
-+ };
-+};
-+*/
-+
-+union audio_cea_channels {
-+ uint8_t all;
-+ struct audio_cea_channels_bits {
-+ uint32_t FL:1;
-+ uint32_t FR:1;
-+ uint32_t LFE:1;
-+ uint32_t FC:1;
-+ uint32_t RL_RC:1;
-+ uint32_t RR:1;
-+ uint32_t RC_RLC_FLC:1;
-+ uint32_t RRC_FRC:1;
-+ } channels;
-+};
-+
-+struct audio_info {
-+ struct audio_info_flags flags;
-+ uint32_t video_latency;
-+ uint32_t audio_latency;
-+ uint32_t display_index;
-+ uint8_t display_name[AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS];
-+ uint32_t manufacture_id;
-+ uint32_t product_id;
-+ /* PortID used for ContainerID when defined */
-+ uint32_t port_id[2];
-+ uint32_t mode_count;
-+ /* this field must be last in this struct */
-+ struct audio_mode modes[DC_MAX_AUDIO_DESC_COUNT];
-+};
-+
-+struct audio_crtc_info {
-+ uint32_t h_total;
-+ uint32_t h_active;
-+ uint32_t v_active;
-+ uint32_t pixel_repetition;
-+ uint32_t requested_pixel_clock; /* in KHz */
-+ uint32_t calculated_pixel_clock; /* in KHz */
-+ uint32_t refresh_rate;
-+ enum dc_color_depth color_depth;
-+ bool interlaced;
-+};
-+
-+/* PLL information required for AZALIA DTO calculation */
-+
-+struct audio_pll_info {
-+ uint32_t dp_dto_source_clock_in_khz;
-+ uint32_t feed_back_divider;
-+ enum audio_dto_source dto_source;
-+ bool ss_enabled;
-+ uint32_t ss_percentage;
-+ uint32_t ss_percentage_divider;
-+};
-+
-+struct audio_channel_associate_info {
-+ union {
-+ struct {
-+ uint32_t ALL_CHANNEL_FL:4;
-+ uint32_t ALL_CHANNEL_FR:4;
-+ uint32_t ALL_CHANNEL_FC:4;
-+ uint32_t ALL_CHANNEL_Sub:4;
-+ uint32_t ALL_CHANNEL_SL:4;
-+ uint32_t ALL_CHANNEL_SR:4;
-+ uint32_t ALL_CHANNEL_BL:4;
-+ uint32_t ALL_CHANNEL_BR:4;
-+ } bits;
-+ uint32_t u32all;
-+ };
-+};
-+
-+struct audio_output {
-+ /* Front DIG id. */
-+ enum engine_id engine_id;
-+ /* encoder output signal */
-+ enum signal_type signal;
-+ /* video timing */
-+ struct audio_crtc_info crtc_info;
-+ /* PLL for audio */
-+ struct audio_pll_info pll_info;
-+};
-+
-+struct audio_feature_support {
-+ /* supported engines*/
-+ uint32_t ENGINE_DIGA:1;
-+ uint32_t ENGINE_DIGB:1;
-+ uint32_t ENGINE_DIGC:1;
-+ uint32_t ENGINE_DIGD:1;
-+ uint32_t ENGINE_DIGE:1;
-+ uint32_t ENGINE_DIGF:1;
-+ uint32_t ENGINE_DIGG:1;
-+ uint32_t ENGINE_DVO:1;
-+ uint32_t MULTISTREAM_AUDIO:1;
-+};
-+
-+enum audio_payload {
-+ CHANNEL_SPLIT_MAPPINGCHANG = 0x9,
-+};
-+
-+#endif /* __AUDIO_TYPES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/bios_parser_interface.h b/drivers/gpu/drm/amd/dal/include/bios_parser_interface.h
-new file mode 100644
-index 0000000..6269164
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/bios_parser_interface.h
-@@ -0,0 +1,294 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_BIOS_PARSER_INTERFACE_H__
-+#define __DAL_BIOS_PARSER_INTERFACE_H__
-+
-+#include "bios_parser_types.h"
-+#include "adapter_service_types.h"
-+#include "gpio_types.h"
-+
-+struct adapter_service;
-+struct bios_parser;
-+
-+struct bp_gpio_cntl_info {
-+ uint32_t id;
-+ enum gpio_pin_output_state state;
-+};
-+
-+enum bp_result {
-+ BP_RESULT_OK = 0, /* There was no error */
-+ BP_RESULT_BADINPUT, /*Bad input parameter */
-+ BP_RESULT_BADBIOSTABLE, /* Bad BIOS table */
-+ BP_RESULT_UNSUPPORTED, /* BIOS Table is not supported */
-+ BP_RESULT_NORECORD, /* Record can't be found */
-+ BP_RESULT_FAILURE
-+};
-+
-+struct bp_init_data {
-+ struct dc_context *ctx;
-+ uint8_t *bios;
-+};
-+
-+struct bios_parser *dal_bios_parser_create(
-+ struct bp_init_data *init,
-+ struct adapter_service *as);
-+void dal_bios_parser_destroy(
-+ struct bios_parser **bp);
-+void dal_bios_parser_power_down(
-+ struct bios_parser *bp);
-+void dal_bios_parser_power_up(
-+ struct bios_parser *bp);
-+
-+uint8_t dal_bios_parser_get_encoders_number(
-+ struct bios_parser *bp);
-+uint8_t dal_bios_parser_get_connectors_number(
-+ struct bios_parser *bp);
-+uint32_t dal_bios_parser_get_oem_ddc_lines_number(
-+ struct bios_parser *bp);
-+struct graphics_object_id dal_bios_parser_get_encoder_id(
-+ struct bios_parser *bp,
-+ uint32_t i);
-+struct graphics_object_id dal_bios_parser_get_connector_id(
-+ struct bios_parser *bp,
-+ uint8_t connector_index);
-+uint32_t dal_bios_parser_get_src_number(
-+ struct bios_parser *bp,
-+ struct graphics_object_id id);
-+uint32_t dal_bios_parser_get_dst_number(
-+ struct bios_parser *bp,
-+ struct graphics_object_id id);
-+uint32_t dal_bios_parser_get_gpio_record(
-+ struct bios_parser *bp,
-+ struct graphics_object_id id,
-+ struct bp_gpio_cntl_info *gpio_record,
-+ uint32_t record_size);
-+enum bp_result dal_bios_parser_get_src_obj(
-+ struct bios_parser *bp,
-+ struct graphics_object_id object_id, uint32_t index,
-+ struct graphics_object_id *src_object_id);
-+enum bp_result dal_bios_parser_get_dst_obj(
-+ struct bios_parser *bp,
-+ struct graphics_object_id object_id, uint32_t index,
-+ struct graphics_object_id *dest_object_id);
-+enum bp_result dal_bios_parser_get_i2c_info(
-+ struct bios_parser *bp,
-+ struct graphics_object_id id,
-+ struct graphics_object_i2c_info *info);
-+enum bp_result dal_bios_parser_get_oem_ddc_info(
-+ struct bios_parser *bp,
-+ uint32_t index,
-+ struct graphics_object_i2c_info *info);
-+enum bp_result dal_bios_parser_get_voltage_ddc_info(
-+ struct bios_parser *bp,
-+ uint32_t index,
-+ struct graphics_object_i2c_info *info);
-+enum bp_result dal_bios_parser_get_thermal_ddc_info(
-+ struct bios_parser *bp,
-+ uint32_t i2c_channel_id,
-+ struct graphics_object_i2c_info *info);
-+enum bp_result dal_bios_parser_get_hpd_info(
-+ struct bios_parser *bp,
-+ struct graphics_object_id id,
-+ struct graphics_object_hpd_info *info);
-+enum bp_result dal_bios_parser_get_device_tag(
-+ struct bios_parser *bp,
-+ struct graphics_object_id connector_object_id,
-+ uint32_t device_tag_index,
-+ struct connector_device_tag_info *info);
-+enum bp_result dal_bios_parser_get_firmware_info(
-+ struct bios_parser *bp,
-+ struct firmware_info *info);
-+enum bp_result dal_bios_parser_get_spread_spectrum_info(
-+ struct bios_parser *bp,
-+ enum as_signal_type signal,
-+ uint32_t index,
-+ struct spread_spectrum_info *ss_info);
-+uint32_t dal_bios_parser_get_ss_entry_number(
-+ struct bios_parser *bp,
-+ enum as_signal_type signal);
-+enum bp_result dal_bios_parser_get_embedded_panel_info(
-+ struct bios_parser *bp,
-+ struct embedded_panel_info *info);
-+enum bp_result dal_bios_parser_enum_embedded_panel_patch_mode(
-+ struct bios_parser *bp,
-+ uint32_t index,
-+ struct embedded_panel_patch_mode *mode);
-+enum bp_result dal_bios_parser_get_gpio_pin_info(
-+ struct bios_parser *bp,
-+ uint32_t gpio_id,
-+ struct gpio_pin_info *info);
-+enum bp_result dal_bios_parser_get_embedded_panel_info(
-+ struct bios_parser *bp,
-+ struct embedded_panel_info *info);
-+enum bp_result dal_bios_parser_get_gpio_pin_info(
-+ struct bios_parser *bp,
-+ uint32_t gpio_id,
-+ struct gpio_pin_info *info);
-+enum bp_result dal_bios_parser_get_faked_edid_len(
-+ struct bios_parser *bp,
-+ uint32_t *len);
-+enum bp_result dal_bios_parser_get_faked_edid_buf(
-+ struct bios_parser *bp,
-+ uint8_t *buff,
-+ uint32_t len);
-+enum bp_result dal_bios_parser_get_encoder_cap_info(
-+ struct bios_parser *bp,
-+ struct graphics_object_id object_id,
-+ struct bp_encoder_cap_info *info);
-+enum bp_result dal_bios_parser_get_din_connector_info(
-+ struct bios_parser *bp,
-+ struct graphics_object_id id,
-+ struct din_connector_info *info);
-+
-+bool dal_bios_parser_is_lid_open(
-+ struct bios_parser *bp);
-+bool dal_bios_parser_is_lid_status_changed(
-+ struct bios_parser *bp);
-+bool dal_bios_parser_is_display_config_changed(
-+ struct bios_parser *bp);
-+bool dal_bios_parser_is_accelerated_mode(
-+ struct bios_parser *bp);
-+void dal_bios_parser_set_scratch_lcd_scale(
-+ struct bios_parser *bp,
-+ enum lcd_scale scale);
-+enum lcd_scale dal_bios_parser_get_scratch_lcd_scale(
-+ struct bios_parser *bp);
-+void dal_bios_parser_get_bios_event_info(
-+ struct bios_parser *bp,
-+ struct bios_event_info *info);
-+void dal_bios_parser_update_requested_backlight_level(
-+ struct bios_parser *bp,
-+ uint32_t backlight_8bit);
-+uint32_t dal_bios_parser_get_requested_backlight_level(
-+ struct bios_parser *bp);
-+void dal_bios_parser_take_backlight_control(
-+ struct bios_parser *bp,
-+ bool cntl);
-+bool dal_bios_parser_is_active_display(
-+ struct bios_parser *bp,
-+ enum signal_type signal,
-+ const struct connector_device_tag_info *device_tag);
-+enum controller_id dal_bios_parser_get_embedded_display_controller_id(
-+ struct bios_parser *bp);
-+uint32_t dal_bios_parser_get_embedded_display_refresh_rate(
-+ struct bios_parser *bp);
-+void dal_bios_parser_set_scratch_connected(
-+ struct bios_parser *bp,
-+ struct graphics_object_id connector_id,
-+ bool connected,
-+ const struct connector_device_tag_info *device_tag);
-+void dal_bios_parser_prepare_scratch_active_and_requested(
-+ struct bios_parser *bp,
-+ enum controller_id controller_id,
-+ enum signal_type signal,
-+ const struct connector_device_tag_info *device_tag);
-+void dal_bios_parser_set_scratch_active_and_requested(
-+ struct bios_parser *bp);
-+void dal_bios_parser_set_scratch_critical_state(
-+ struct bios_parser *bp,
-+ bool state);
-+void dal_bios_parser_set_scratch_acc_mode_change(
-+ struct bios_parser *bp);
-+
-+bool dal_bios_parser_is_device_id_supported(
-+ struct bios_parser *bp,
-+ struct device_id id);
-+
-+/* COMMANDS */
-+
-+enum bp_result dal_bios_parser_encoder_control(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl);
-+enum bp_result dal_bios_parser_transmitter_control(
-+ struct bios_parser *bp,
-+ struct bp_transmitter_control *cntl);
-+enum bp_result dal_bios_parser_crt_control(
-+ struct bios_parser *bp,
-+ enum engine_id engine_id,
-+ bool enable,
-+ uint32_t pixel_clock);
-+enum bp_result dal_bios_parser_dvo_encoder_control(
-+ struct bios_parser *bp,
-+ struct bp_dvo_encoder_control *cntl);
-+enum bp_result dal_bios_parser_enable_crtc(
-+ struct bios_parser *bp,
-+ enum controller_id id,
-+ bool enable);
-+enum bp_result dal_bios_parser_adjust_pixel_clock(
-+ struct bios_parser *bp,
-+ struct bp_adjust_pixel_clock_parameters *bp_params);
-+enum bp_result dal_bios_parser_set_pixel_clock(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params);
-+enum bp_result dal_bios_parser_enable_spread_spectrum_on_ppll(
-+ struct bios_parser *bp,
-+ struct bp_spread_spectrum_parameters *bp_params,
-+ bool enable);
-+enum bp_result dal_bios_parser_program_crtc_timing(
-+ struct bios_parser *bp,
-+ struct bp_hw_crtc_timing_parameters *bp_params);
-+enum bp_result dal_bios_parser_blank_crtc(
-+ struct bios_parser *bp,
-+ struct bp_blank_crtc_parameters *bp_params,
-+ bool blank);
-+enum bp_result dal_bios_parser_set_overscan(
-+ struct bios_parser *bp,
-+ struct bp_hw_crtc_overscan_parameters *bp_params);
-+enum bp_result dal_bios_parser_crtc_source_select(
-+ struct bios_parser *bp,
-+ struct bp_crtc_source_select *bp_params);
-+enum bp_result dal_bios_parser_program_display_engine_pll(
-+ struct bios_parser *bp,
-+ struct bp_pixel_clock_parameters *bp_params);
-+enum bp_result dal_bios_parser_get_divider_for_target_display_clock(
-+ struct bios_parser *bp,
-+ struct bp_display_clock_parameters *bp_params);
-+enum signal_type dal_bios_parser_dac_load_detect(
-+ struct bios_parser *bp,
-+ struct graphics_object_id encoder,
-+ struct graphics_object_id connector,
-+ enum signal_type display_signal);
-+enum bp_result dal_bios_parser_enable_memory_requests(
-+ struct bios_parser *bp,
-+ enum controller_id controller_id,
-+ bool enable);
-+enum bp_result dal_bios_parser_external_encoder_control(
-+ struct bios_parser *bp,
-+ struct bp_external_encoder_control *cntl);
-+enum bp_result dal_bios_parser_enable_disp_power_gating(
-+ struct bios_parser *bp,
-+ enum controller_id controller_id,
-+ enum bp_pipe_control_action action);
-+
-+void dal_bios_parser_post_init(struct bios_parser *bp);
-+
-+/* Parse integrated BIOS info */
-+struct integrated_info *dal_bios_parser_create_integrated_info(
-+ struct bios_parser *bp);
-+
-+/* Destroy provided integrated info */
-+void dal_bios_parser_destroy_integrated_info(struct dc_context *ctx, struct integrated_info **info);
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/bios_parser_types.h b/drivers/gpu/drm/amd/dal/include/bios_parser_types.h
-new file mode 100644
-index 0000000..da7d5f2
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/bios_parser_types.h
-@@ -0,0 +1,305 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_BIOS_PARSER_TYPES_H__
-+#define __DAL_BIOS_PARSER_TYPES_H__
-+
-+#include "include/signal_types.h"
-+#include "include/grph_object_ctrl_defs.h"
-+#include "link_service_types.h"
-+
-+enum bp_encoder_control_action {
-+ /* direct VBIOS translation! Just to simplify the translation */
-+ ENCODER_CONTROL_DISABLE = 0,
-+ ENCODER_CONTROL_ENABLE,
-+ ENCODER_CONTROL_SETUP,
-+ ENCODER_CONTROL_INIT
-+};
-+
-+enum bp_transmitter_control_action {
-+ /* direct VBIOS translation! Just to simplify the translation */
-+ TRANSMITTER_CONTROL_DISABLE = 0,
-+ TRANSMITTER_CONTROL_ENABLE,
-+ TRANSMITTER_CONTROL_BACKLIGHT_OFF,
-+ TRANSMITTER_CONTROL_BACKLIGHT_ON,
-+ TRANSMITTER_CONTROL_BACKLIGHT_BRIGHTNESS,
-+ TRANSMITTER_CONTROL_LCD_SETF_TEST_START,
-+ TRANSMITTER_CONTROL_LCD_SELF_TEST_STOP,
-+ TRANSMITTER_CONTROL_INIT,
-+ TRANSMITTER_CONTROL_DEACTIVATE,
-+ TRANSMITTER_CONTROL_ACTIAVATE,
-+ TRANSMITTER_CONTROL_SETUP,
-+ TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS,
-+ /* ATOM_TRANSMITTER_ACTION_POWER_ON. This action is for eDP only
-+ * (power up the panel)
-+ */
-+ TRANSMITTER_CONTROL_POWER_ON,
-+ /* ATOM_TRANSMITTER_ACTION_POWER_OFF. This action is for eDP only
-+ * (power down the panel)
-+ */
-+ TRANSMITTER_CONTROL_POWER_OFF
-+};
-+
-+enum bp_external_encoder_control_action {
-+ EXTERNAL_ENCODER_CONTROL_DISABLE = 0,
-+ EXTERNAL_ENCODER_CONTROL_ENABLE = 1,
-+ EXTERNAL_ENCODER_CONTROL_INIT = 0x7,
-+ EXTERNAL_ENCODER_CONTROL_SETUP = 0xf,
-+ EXTERNAL_ENCODER_CONTROL_UNBLANK = 0x10,
-+ EXTERNAL_ENCODER_CONTROL_BLANK = 0x11,
-+ EXTERNAL_ENCODER_CONTROL_DAC_LOAD_DETECT = 0x12
-+};
-+
-+enum bp_pipe_control_action {
-+ ASIC_PIPE_DISABLE = 0,
-+ ASIC_PIPE_ENABLE,
-+ ASIC_PIPE_INIT
-+};
-+
-+struct bp_encoder_control {
-+ enum bp_encoder_control_action action;
-+ enum engine_id engine_id;
-+ enum transmitter transmitter;
-+ enum signal_type signal;
-+ enum lane_count lanes_number;
-+ enum dc_color_depth color_depth;
-+ bool enable_dp_audio;
-+ uint32_t pixel_clock; /* khz */
-+};
-+
-+struct bp_external_encoder_control {
-+ enum bp_external_encoder_control_action action;
-+ enum engine_id engine_id;
-+ enum link_rate link_rate;
-+ enum lane_count lanes_number;
-+ enum signal_type signal;
-+ enum dc_color_depth color_depth;
-+ bool coherent;
-+ struct graphics_object_id encoder_id;
-+ struct graphics_object_id connector_obj_id;
-+ uint32_t pixel_clock; /* in KHz */
-+};
-+
-+struct bp_crtc_source_select {
-+ enum engine_id engine_id;
-+ enum controller_id controller_id;
-+ /* from GPU Tx aka asic_signal */
-+ enum signal_type signal;
-+ /* sink_signal may differ from asicSignal if Translator encoder */
-+ enum signal_type sink_signal;
-+ enum display_output_bit_depth display_output_bit_depth;
-+ bool enable_dp_audio;
-+};
-+
-+struct bp_transmitter_control {
-+ enum bp_transmitter_control_action action;
-+ enum engine_id engine_id;
-+ enum transmitter transmitter; /* PhyId */
-+ enum lane_count lanes_number;
-+ enum clock_source_id pll_id; /* needed for DCE 4.0 */
-+ enum signal_type signal;
-+ enum dc_color_depth color_depth; /* not used for DCE6.0 */
-+ enum hpd_source_id hpd_sel; /* ucHPDSel, used for DCe6.0 */
-+ struct graphics_object_id connector_obj_id;
-+ /* symClock; in 10kHz, pixel clock, in HDMI deep color mode, it should
-+ * be pixel clock * deep_color_ratio (in KHz)
-+ */
-+ uint32_t pixel_clock;
-+ uint32_t lane_select;
-+ uint32_t lane_settings;
-+ bool coherent;
-+ bool multi_path;
-+ bool single_pll_mode;
-+};
-+
-+enum dvo_encoder_memory_rate {
-+ DVO_ENCODER_MEMORY_RATE_DDR,
-+ DVO_ENCODER_MEMORY_RATE_SDR
-+};
-+
-+enum dvo_encoder_interface_width {
-+ DVO_ENCODER_INTERFACE_WIDTH_LOW12BIT,
-+ DVO_ENCODER_INTERFACE_WIDTH_HIGH12BIT,
-+ DVO_ENCODER_INTERFACE_WIDTH_FULL24BIT
-+};
-+
-+struct bp_dvo_encoder_control {
-+ enum bp_encoder_control_action action;
-+ enum dvo_encoder_memory_rate memory_rate;
-+ enum dvo_encoder_interface_width interface_width;
-+ uint32_t pixel_clock; /* in KHz */
-+};
-+
-+struct bp_blank_crtc_parameters {
-+ enum controller_id controller_id;
-+ uint32_t black_color_rcr;
-+ uint32_t black_color_gy;
-+ uint32_t black_color_bcb;
-+};
-+
-+struct bp_hw_crtc_timing_parameters {
-+ enum controller_id controller_id;
-+ /* horizontal part */
-+ uint32_t h_total;
-+ uint32_t h_addressable;
-+ uint32_t h_overscan_left;
-+ uint32_t h_overscan_right;
-+ uint32_t h_sync_start;
-+ uint32_t h_sync_width;
-+
-+ /* vertical part */
-+ uint32_t v_total;
-+ uint32_t v_addressable;
-+ uint32_t v_overscan_top;
-+ uint32_t v_overscan_bottom;
-+ uint32_t v_sync_start;
-+ uint32_t v_sync_width;
-+
-+ struct timing_flags {
-+ uint32_t INTERLACE:1;
-+ uint32_t PIXEL_REPETITION:4;
-+ uint32_t HSYNC_POSITIVE_POLARITY:1;
-+ uint32_t VSYNC_POSITIVE_POLARITY:1;
-+ uint32_t HORZ_COUNT_BY_TWO:1;
-+ } flags;
-+};
-+
-+struct bp_hw_crtc_overscan_parameters {
-+ enum controller_id controller_id;
-+ uint32_t h_overscan_left;
-+ uint32_t h_overscan_right;
-+ uint32_t v_overscan_top;
-+ uint32_t v_overscan_bottom;
-+};
-+
-+struct bp_adjust_pixel_clock_parameters {
-+ /* Input: Signal Type - to be converted to Encoder mode */
-+ enum signal_type signal_type;
-+ /* Input: required by V3, display pll configure parameter defined as
-+ * following DISPPLL_CONFIG_XXXX */
-+ enum disp_pll_config display_pll_config;
-+ /* Input: Encoder object id */
-+ struct graphics_object_id encoder_object_id;
-+ /* Input: Pixel Clock (requested Pixel clock based on Video timing
-+ * standard used) in KHz
-+ */
-+ uint32_t pixel_clock;
-+ union {
-+ /* Input: If DVO, need passing link rate and output 12bit low or
-+ * 24bit to VBIOS Exec table */
-+ uint32_t dvo_config;
-+ /* Input: If non DVO, not defined yet */
-+ uint32_t non_dvo_undefined;
-+ };
-+ /* Output: Adjusted Pixel Clock (after VBIOS exec table) in KHz */
-+ uint32_t adjusted_pixel_clock;
-+ /* Output: If non-zero, this refDiv value should be used to calculate
-+ * other ppll params */
-+ uint32_t reference_divider;
-+ /* Output: If non-zero, this postDiv value should be used to calculate
-+ * other ppll params */
-+ uint32_t pixel_clock_post_divider;
-+ /* Input: Enable spread spectrum */
-+ bool ss_enable;
-+};
-+
-+struct bp_pixel_clock_parameters {
-+ enum controller_id controller_id; /* (Which CRTC uses this PLL) */
-+ enum clock_source_id pll_id; /* Clock Source Id */
-+ /* signal_type -> Encoder Mode - needed by VBIOS Exec table */
-+ enum signal_type signal_type;
-+ /* Adjusted Pixel Clock (after VBIOS exec table)
-+ * that becomes Target Pixel Clock (KHz) */
-+ uint32_t target_pixel_clock;
-+ /* Calculated Reference divider of Display PLL */
-+ uint32_t reference_divider;
-+ /* Calculated Feedback divider of Display PLL */
-+ uint32_t feedback_divider;
-+ /* Calculated Fractional Feedback divider of Display PLL */
-+ uint32_t fractional_feedback_divider;
-+ /* Calculated Pixel Clock Post divider of Display PLL */
-+ uint32_t pixel_clock_post_divider;
-+ struct graphics_object_id encoder_object_id; /* Encoder object id */
-+ /* If DVO, need passing link rate and output 12bit low or
-+ * 24bit to VBIOS Exec table */
-+ uint32_t dvo_config;
-+ /* VBIOS returns a fixed display clock when DFS-bypass feature
-+ * is enabled (KHz) */
-+ uint32_t dfs_bypass_display_clock;
-+ struct program_pixel_clock_flags {
-+ uint32_t FORCE_PROGRAMMING_OF_PLL:1;
-+ /* Use Engine Clock as source for Display Clock when
-+ * programming PLL */
-+ uint32_t USE_E_CLOCK_AS_SOURCE_FOR_D_CLOCK:1;
-+ /* Use external reference clock (refDivSrc for PLL) */
-+ uint32_t SET_EXTERNAL_REF_DIV_SRC:1;
-+ } flags;
-+};
-+
-+struct bp_display_clock_parameters {
-+ uint32_t target_display_clock; /* KHz */
-+ /* Actual Display Clock set due to clock divider granularity KHz */
-+ uint32_t actual_display_clock;
-+ /* Actual Post Divider ID used to generate the actual clock */
-+ uint32_t actual_post_divider_id;
-+};
-+
-+struct spread_spectrum_flags {
-+ /* 1 = Center Spread; 0 = down spread */
-+ uint32_t CENTER_SPREAD:1;
-+ /* 1 = external; 0 = internal */
-+ uint32_t EXTERNAL_SS:1;
-+ /* 1 = delta-sigma type parameter; 0 = ver1 */
-+ uint32_t DS_TYPE:1;
-+};
-+
-+struct bp_spread_spectrum_parameters {
-+ enum clock_source_id pll_id;
-+ uint32_t percentage;
-+ uint32_t ds_frac_amount;
-+
-+ union {
-+ struct {
-+ uint32_t step;
-+ uint32_t delay;
-+ uint32_t range; /* In Hz unit */
-+ } ver1;
-+ struct {
-+ uint32_t feedback_amount;
-+ uint32_t nfrac_amount;
-+ uint32_t ds_frac_size;
-+ } ds;
-+ };
-+
-+ struct spread_spectrum_flags flags;
-+};
-+
-+struct bp_encoder_cap_info {
-+ uint32_t DP_HBR2_CAP:1;
-+ uint32_t DP_HBR2_EN:1;
-+ uint32_t RESERVED:30;
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/bit_set.h b/drivers/gpu/drm/amd/dal/include/bit_set.h
-new file mode 100644
-index 0000000..3cd8d32
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/bit_set.h
-@@ -0,0 +1,61 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_BIT_SET_H__
-+#define __DAL_BIT_SET_H__
-+
-+struct bit_set_iterator_32 {
-+ uint32_t value;
-+};
-+
-+static inline uint32_t least_significant_bit(uint32_t bs32_container)
-+{
-+ return bs32_container & (0 - bs32_container);
-+}
-+/* iterates over bit_set_iterator by means of least significant bit purge*/
-+static inline uint32_t get_next_significant_bit(
-+ struct bit_set_iterator_32 *bs32)
-+{
-+ uint32_t lsb = least_significant_bit(bs32->value);
-+
-+ bs32->value &= ~lsb;
-+ return lsb;
-+}
-+
-+static inline void bit_set_iterator_reset_to_mask(
-+ struct bit_set_iterator_32 *bs32,
-+ uint32_t mask)
-+{
-+ bs32->value = mask;
-+}
-+
-+static inline void bit_set_iterator_construct(
-+ struct bit_set_iterator_32 *bs32,
-+ uint32_t mask)
-+{
-+ bit_set_iterator_reset_to_mask(bs32, mask);
-+}
-+
-+#endif /* __DAL_BIT_SET_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/clock_source_interface.h b/drivers/gpu/drm/amd/dal/include/clock_source_interface.h
-new file mode 100644
-index 0000000..bea4c2b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/clock_source_interface.h
-@@ -0,0 +1,89 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_CLOCK_SOURCE_INTERFACE__
-+#define __DAL_CLOCK_SOURCE_INTERFACE__
-+
-+#include "include/clock_source_types.h"
-+
-+struct clock_source;
-+struct clock_source_init_data {
-+ struct adapter_service *as;
-+ struct graphics_object_id clk_src_id;
-+ struct dc_context *ctx;
-+};
-+
-+struct clock_source *dal_clock_source_create(struct clock_source_init_data *);
-+
-+void dal_clock_source_destroy(struct clock_source **clk_src);
-+
-+enum clock_source_id dal_clock_source_get_id(
-+ const struct clock_source *clk_src);
-+
-+bool dal_clock_source_is_clk_src_with_fixed_freq(
-+ const struct clock_source *clk_src);
-+
-+const struct graphics_object_id dal_clock_source_get_graphics_object_id(
-+ const struct clock_source *clk_src);
-+
-+enum clock_sharing_level dal_clock_souce_get_clk_sharing_lvl(
-+ const struct clock_source *clk_src);
-+
-+uint32_t dal_clock_source_get_pix_clk_dividers(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings);
-+
-+bool dal_clock_source_program_pix_clk(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings);
-+
-+bool dal_clock_source_adjust_pxl_clk_by_ref_pixel_rate(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ uint32_t pix_clk_hz);
-+
-+bool dal_clock_source_adjust_pxl_clk_by_pix_amount(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ int32_t pix_num);
-+
-+uint32_t dal_clock_source_retreive_pix_rate_hz(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params);
-+
-+bool dal_clock_source_power_down_pll(struct clock_source *clk_src,
-+ enum controller_id);
-+
-+bool dal_clock_source_is_clk_in_reset(struct clock_source *clk_src);
-+
-+bool dal_clock_source_is_gen_lock_capable(struct clock_source *clk_src);
-+
-+bool dal_clock_source_is_output_signal_supported(
-+ const struct clock_source *clk_src,
-+ enum signal_type signal_type);
-+
-+#endif /*__DAL_CLOCK_SOURCE_INTERFACE__*/
-diff --git a/drivers/gpu/drm/amd/dal/include/clock_source_types.h b/drivers/gpu/drm/amd/dal/include/clock_source_types.h
-new file mode 100644
-index 0000000..3883216
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/clock_source_types.h
-@@ -0,0 +1,118 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_CLOCK_SOURCE_TYPES_H__
-+#define __DAL_CLOCK_SOURCE_TYPES_H__
-+
-+#include "include/signal_types.h"
-+#include "include/grph_object_ctrl_defs.h"
-+
-+/**
-+ * ClockSharingLevel
-+ * Enumeration for clock sharing support.
-+ * Level <x> means sharing supported on all levels below and including <x>
-+ */
-+enum clock_sharing_level {
-+ CLOCK_SHARING_LEVEL_NOT_SHAREABLE = 0,
-+ CLOCK_SHARING_LEVEL_DP_MST_SHAREABLE,
-+ CLOCK_SHARING_LEVEL_DISPLAY_PORT_SHAREABLE
-+};
-+
-+/**
-+ * Display Port HW De spread of Reference Clock related Parameters structure
-+ * Store it once at boot for later usage
-+ */
-+struct csdp_ref_clk_ds_params {
-+ bool hw_dso_n_dp_ref_clk;
-+/* Flag for HW De Spread enabled (if enabled SS on DP Reference Clock)*/
-+ uint32_t avg_dp_ref_clk_khz;
-+/* Average DP Reference clock (in KHz)*/
-+ uint32_t ss_percentage_on_dp_ref_clk;
-+/* DP Reference clock SS percentage
-+ * (not to be mixed with DP IDCLK SS from PLL Settings)*/
-+ uint32_t ss_percentage_divider;
-+/* DP Reference clock SS percentage divider */
-+};
-+
-+/**
-+ * Pixel Clock Parameters structure
-+ * These parameters are required as input
-+ * when calculating Pixel Clock Dividers for requested Pixel Clock
-+ */
-+struct pixel_clk_flags {
-+ uint32_t ENABLE_SS:1;
-+ uint32_t DISPLAY_BLANKED:1;
-+ uint32_t PROGRAM_PIXEL_CLOCK:1;
-+ uint32_t PROGRAM_ID_CLOCK:1;
-+};
-+
-+struct pixel_clk_params {
-+ uint32_t requested_pix_clk; /* in KHz */
-+/*> Requested Pixel Clock
-+ * (based on Video Timing standard used for requested mode)*/
-+ uint32_t requested_sym_clk; /* in KHz */
-+/*> Requested Sym Clock (relevant only for display port)*/
-+ uint32_t dp_ref_clk; /* in KHz */
-+/*> DP reference clock - calculated only for DP signal for specific cases*/
-+ struct graphics_object_id encoder_object_id;
-+/*> Encoder object Id - needed by VBIOS Exec table*/
-+ enum signal_type signal_type;
-+/*> signalType -> Encoder Mode - needed by VBIOS Exec table*/
-+ enum controller_id controller_id;
-+/*> ControllerId - which controller using this PLL*/
-+ enum dc_color_depth color_depth;
-+ struct csdp_ref_clk_ds_params de_spread_params;
-+/*> de-spread info, relevant only for on-the-fly tune-up pixel rate*/
-+
-+ uint32_t dvo_cfg;
-+/*> If DVO, need passing link rate
-+ * and output 12bit low or 24bit to VBIOS Exec table*/
-+
-+ enum disp_pll_config disp_pll_cfg;
-+ struct pixel_clk_flags flags;
-+};
-+
-+/**
-+ * Pixel Clock Dividers structure with desired Pixel Clock
-+ * (adjusted after VBIOS exec table),
-+ * with actually calculated Clock and reference Crystal frequency
-+ */
-+struct pll_settings {
-+ uint32_t actual_pix_clk;
-+ uint32_t adjusted_pix_clk;
-+ uint32_t calculated_pix_clk;
-+ uint32_t vco_freq;
-+ uint32_t reference_freq;
-+ uint32_t reference_divider;
-+ uint32_t feedback_divider;
-+ uint32_t fract_feedback_divider;
-+ uint32_t pix_clk_post_divider;
-+ uint32_t ss_percentage;
-+ bool use_external_clk;
-+};
-+
-+#define MAX_PLL_CALC_ERROR 0xFFFFFFFF
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/connector_interface.h b/drivers/gpu/drm/amd/dal/include/connector_interface.h
-new file mode 100644
-index 0000000..e09af7e
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/connector_interface.h
-@@ -0,0 +1,82 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_CONNECTOR_INTERFACE_H__
-+#define __DAL_CONNECTOR_INTERFACE_H__
-+
-+#include "adapter_service_interface.h"
-+#include "signal_types.h"
-+
-+/* forward declaration */
-+struct connector;
-+
-+struct connector_signals {
-+ const enum signal_type *signal;
-+ uint32_t number_of_signals;
-+};
-+
-+struct connector_feature_support {
-+ bool HPD_FILTERING:1;
-+ bool HW_DDC_POLLING:1;
-+ enum hpd_source_id hpd_line;
-+ enum channel_id ddc_line;
-+};
-+
-+void dal_connector_get_features(
-+ const struct connector *con,
-+ struct connector_feature_support *cfs);
-+
-+struct connector *dal_connector_create(
-+ struct dc_context *ctx,
-+ struct adapter_service *as,
-+ struct graphics_object_id go_id);
-+
-+void dal_connector_destroy(struct connector **connector);
-+
-+void dal_connector_destroy(struct connector **connector);
-+
-+const struct graphics_object_id dal_connector_get_graphics_object_id(
-+ const struct connector *connector);
-+
-+uint32_t dal_connector_enumerate_output_signals(
-+ const struct connector *connector);
-+uint32_t dal_connector_enumerate_input_signals(
-+ const struct connector *connector);
-+
-+struct connector_signals dal_connector_get_default_signals(
-+ const struct connector *connector);
-+
-+bool dal_connector_program_hpd_filter(
-+ const struct connector *connector,
-+ const uint32_t delay_on_connect_in_ms,
-+ const uint32_t delay_on_disconnect_in_ms);
-+
-+bool dal_connector_enable_ddc_polling(
-+ const struct connector *connector,
-+ const bool is_poll_for_connect);
-+
-+bool dal_connector_disable_ddc_polling(const struct connector *connector);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/dal_asic_id.h b/drivers/gpu/drm/amd/dal/include/dal_asic_id.h
-new file mode 100644
-index 0000000..fa04f80
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/dal_asic_id.h
-@@ -0,0 +1,106 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_ASIC_ID_H__
-+#define __DAL_ASIC_ID_H__
-+
-+/*
-+ * ASIC internal revision ID
-+ */
-+
-+/* DCE80 (based on ci_id.h in Perforce) */
-+
-+#define CI_BONAIRE_M_A0 0x14
-+#define CI_BONAIRE_M_A1 0x15
-+#define CI_HAWAII_P_A0 0x28
-+
-+#define CI_UNKNOWN 0xFF
-+
-+#define ASIC_REV_IS_BONAIRE_M(rev) \
-+ ((rev >= CI_BONAIRE_M_A0) && (rev < CI_HAWAII_P_A0))
-+
-+#define ASIC_REV_IS_HAWAII_P(rev) \
-+ (rev >= CI_HAWAII_P_A0)
-+
-+/* KV1 with Spectre GFX core, 8-8-1-2 (CU-Pix-Primitive-RB) */
-+#define KV_SPECTRE_A0 0x01
-+
-+/* KV2 with Spooky GFX core, including downgraded from Spectre core,
-+ * 3-4-1-1 (CU-Pix-Primitive-RB) */
-+#define KV_SPOOKY_A0 0x41
-+
-+/* KB with Kalindi GFX core, 2-4-1-1 (CU-Pix-Primitive-RB) */
-+#define KB_KALINDI_A0 0x81
-+
-+/* KB with Kalindi GFX core, 2-4-1-1 (CU-Pix-Primitive-RB) */
-+#define KB_KALINDI_A1 0x82
-+
-+/* BV with Kalindi GFX core, 2-4-1-1 (CU-Pix-Primitive-RB) */
-+#define BV_KALINDI_A2 0x85
-+
-+/* ML with Godavari GFX core, 2-4-1-1 (CU-Pix-Primitive-RB) */
-+#define ML_GODAVARI_A0 0xA1
-+
-+/* ML with Godavari GFX core, 2-4-1-1 (CU-Pix-Primitive-RB) */
-+#define ML_GODAVARI_A1 0xA2
-+
-+#define KV_UNKNOWN 0xFF
-+
-+#define ASIC_REV_IS_KALINDI(rev) \
-+ ((rev >= KB_KALINDI_A0) && (rev < KV_UNKNOWN))
-+
-+#define ASIC_REV_IS_BHAVANI(rev) \
-+ ((rev >= BV_KALINDI_A2) && (rev < ML_GODAVARI_A0))
-+
-+#define ASIC_REV_IS_GODAVARI(rev) \
-+ ((rev >= ML_GODAVARI_A0) && (rev < KV_UNKNOWN))
-+
-+/* DCE11 */
-+#define CZ_CARRIZO_A0 0x01
-+
-+#define STONEY_A0 0x61
-+#define CZ_UNKNOWN 0xFF
-+
-+#define ASIC_REV_IS_STONEY(rev) \
-+ ((rev >= STONEY_A0) && (rev < CZ_UNKNOWN))
-+
-+/*
-+ * ASIC chip ID
-+ */
-+/* DCE80 */
-+#define DEVICE_ID_KALINDI_9834 0x9834
-+#define DEVICE_ID_TEMASH_9839 0x9839
-+#define DEVICE_ID_TEMASH_983D 0x983D
-+
-+
-+/* Asic Family IDs for different asic family. */
-+#define FAMILY_CI 120 /* Sea Islands: Hawaii (P), Bonaire (M) */
-+#define FAMILY_KV 125 /* Fusion => Kaveri: Spectre, Spooky; Kabini: Kalindi */
-+#define FAMILY_VI 130 /* Volcanic Islands: Iceland (V), Tonga (M) */
-+#define FAMILY_CZ 135 /* Carrizo */
-+
-+#define FAMILY_UNKNOWN 0xFF
-+
-+#endif /* __DAL_ASIC_ID_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/dal_register_logger.h b/drivers/gpu/drm/amd/dal/include/dal_register_logger.h
-new file mode 100644
-index 0000000..176d811
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/dal_register_logger.h
-@@ -0,0 +1,43 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_REGISTER_LOGGER__
-+#define __DAL_REGISTER_LOGGER__
-+
-+/****************
-+ * API functions
-+ ***************/
-+
-+/* dal_reg_logger_push - begin Register Logging */
-+void dal_reg_logger_push(const char *caller_func);
-+/* dal_reg_logger_pop - stop Register Logging */
-+void dal_reg_logger_pop(void);
-+
-+
-+/* for internal use of the Logger only */
-+void dal_reg_logger_rw_count_increment(void);
-+bool dal_reg_logger_should_dump_register(void);
-+
-+#endif /* __DAL_REGISTER_LOGGER__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/dal_types.h b/drivers/gpu/drm/amd/dal/include/dal_types.h
-new file mode 100644
-index 0000000..d3c91b9
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/dal_types.h
-@@ -0,0 +1,292 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_TYPES_H__
-+#define __DAL_TYPES_H__
-+
-+#include "dcs_types.h"
-+struct dal_logger;
-+
-+enum dce_version {
-+ DCE_VERSION_UNKNOWN = (-1),
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ DCE_VERSION_11_0,
-+#endif
-+ DCE_VERSION_MAX
-+};
-+
-+/*
-+ * ASIC Runtime Flags
-+ */
-+struct dal_asic_runtime_flags {
-+ union {
-+ uint32_t raw;
-+ struct {
-+ uint32_t EMULATE_REPLUG_ON_CAP_CHANGE:1;
-+ uint32_t SUPPORT_XRBIAS:1;
-+ uint32_t SKIP_POWER_DOWN_ON_RESUME:1;
-+ uint32_t FULL_DETECT_ON_RESUME:1;
-+ uint32_t GSL_FRAMELOCK:1;
-+ uint32_t NO_LOW_BPP_MODES:1;
-+ uint32_t BLOCK_ON_INITIAL_DETECTION:1;
-+ uint32_t OPTIMIZED_DISPLAY_PROGRAMMING_ON_BOOT:1;
-+ uint32_t DRIVER_CONTROLLED_BRIGHTNESS:1;
-+ uint32_t MODIFIABLE_FRAME_DURATION:1;
-+ uint32_t MIRACAST_SUPPORTED:1;
-+ uint32_t CONNECTED_STANDBY_SUPPORTED:1;
-+ uint32_t GNB_WAKEUP_SUPPORTED:1;
-+ } bits;
-+ } flags;
-+};
-+
-+struct hw_asic_id {
-+ uint32_t chip_id;
-+ uint32_t chip_family;
-+ uint32_t pci_revision_id;
-+ uint32_t hw_internal_rev;
-+ uint32_t vram_type;
-+ uint32_t vram_width;
-+ uint32_t feature_flags;
-+ struct dal_asic_runtime_flags runtime_flags;
-+ uint32_t fake_paths_num;
-+ void *atombios_base_address;
-+};
-+
-+/* this is pci information. BDF stands for BUS,DEVICE,FUNCTION*/
-+
-+struct bdf_info {
-+ uint16_t BUS_NUMBER:8;
-+ uint16_t DEVICE_NUMBER:5;
-+ uint16_t FUNCTION_NUMBER:3;
-+};
-+
-+#define DAL_PARAM_INVALID_INT 0x80000000
-+
-+/* shift values for bool override parameter mask
-+ * bmask is for this struct,if we touch this feature
-+ * bval indicates every bit fields for this struct too,1 is enable this feature
-+ * amdgpu.disp_bval=1594, amdgpu.disp_bmask=1594 ,
-+ * finally will show log like this:
-+ * Overridden FEATURE_LIGHT_SLEEP is enabled now
-+ * Overridden FEATURE_USE_MAX_DISPLAY_CLK is enabled now
-+ * Overridden FEATURE_ENABLE_DFS_BYPASS is enabled now
-+ * Overridden FEATURE_POWER_GATING_PIPE_IN_TILE is enabled now
-+ * Overridden FEATURE_USE_PPLIB is enabled now
-+ * Overridden FEATURE_DISABLE_LPT_SUPPORT is enabled now
-+ * Overridden FEATURE_DUMMY_FBC_BACKEND is enabled now */
-+enum bool_param_shift {
-+ DAL_PARAM_MAXIMIZE_STUTTER_MARKS = 0,
-+ DAL_PARAM_LIGHT_SLEEP,
-+ DAL_PARAM_MAXIMIZE_URGENCY_WATERMARKS,
-+ DAL_PARAM_USE_MAX_DISPLAY_CLK,
-+ DAL_PARAM_ENABLE_DFS_BYPASS,
-+ DAL_PARAM_POWER_GATING_PIPE_IN_TILE,
-+ DAL_PARAM_POWER_GATING_LB_PORTION,
-+ DAL_PARAM_PSR_ENABLE,
-+ DAL_PARAM_VARI_BRIGHT_ENABLE,
-+ DAL_PARAM_USE_PPLIB,
-+ DAL_PARAM_DISABLE_LPT_SUPPORT,
-+ DAL_PARAM_DUMMY_FBC_BACKEND,
-+ DAL_PARAM_ENABLE_GPU_SCALING,
-+ DAL_BOOL_PARAM_MAX
-+};
-+
-+/* array index for integer override parameters*/
-+enum int_param_array_index {
-+ DAL_PARAM_MAX_COFUNC_NON_DP_DISPLAYS = 0,
-+ DAL_PARAM_DRR_SUPPORT,
-+ DAL_INT_PARAM_MAX
-+};
-+
-+struct dal_override_parameters {
-+ uint32_t bool_param_enable_mask;
-+ uint32_t bool_param_values;
-+ uint32_t int_param_values[DAL_INT_PARAM_MAX];
-+};
-+
-+
-+struct dal_init_data {
-+ struct hw_asic_id asic_id;
-+ struct view_port_alignment vp_alignment;
-+ struct bdf_info bdf_info;
-+ struct dal_override_parameters display_param;
-+ void *driver; /* ctx */
-+ void *cgs_device;
-+};
-+
-+struct dal_dc_init_data {
-+ struct dc_context *ctx; /* TODO: remove 'dal' when DC is complete. */
-+ struct adapter_service *adapter_srv;
-+};
-+
-+struct dal_dev_c_lut {
-+ uint8_t red;
-+ uint8_t green;
-+ uint8_t blue;
-+ uint8_t reserved;
-+};
-+
-+struct dal_dev_gamma_lut {
-+ uint16_t red;
-+ uint16_t green;
-+ uint16_t blue;
-+};
-+
-+struct dc_context {
-+ struct dc *dc;
-+
-+ void *driver_context; /* e.g. amdgpu_device */
-+
-+ struct dal_logger *logger;
-+ void *cgs_device;
-+};
-+
-+/* Wireless display structs */
-+
-+union dal_remote_display_cea_mode_bitmap {
-+ struct {
-+ uint32_t CEA_640X480_60P:1;/*0*/
-+ uint32_t CEA_720X480_60P:1;/*1*/
-+ uint32_t CEA_720X480_60I:1;/*2*/
-+ uint32_t CEA_720X576_50P:1;/*3*/
-+ uint32_t CEA_720X576_50I:1;/*4*/
-+ uint32_t CEA_1280X720_30P:1;/*5*/
-+ uint32_t CEA_1280X720_60P:1;/*6*/
-+ uint32_t CEA_1920X1080_30P:1;/*7*/
-+ uint32_t CEA_1920X1080_60P:1;/*8*/
-+ uint32_t CEA_1920X1080_60I:1;/*9*/
-+ uint32_t CEA_1280X720_25P:1;/*10*/
-+ uint32_t CEA_1280X728_50P:1;/*11*/
-+ uint32_t CEA_1920X1080_25P:1;/*12*/
-+ uint32_t CEA_1920X1080_50P:1;/*13*/
-+ uint32_t CEA_1920X1080_50I:1;/*14*/
-+ uint32_t CEA_1280X1024_24P:1;/*15*/
-+ uint32_t CEA_1920X1080_24P:1;/*16*/
-+ uint32_t RESERVED:15;/*[17-31]*/
-+ } flags;
-+ uint32_t raw;
-+};
-+
-+union dal_remote_display_vesa_mode_bitmap {
-+ struct {
-+ uint32_t VESA_800X600_30P:1;/*0*/
-+ uint32_t VESA_800X600_60P:1;/*1*/
-+ uint32_t VESA_1024X768_30P:1;/*2*/
-+ uint32_t VESA_1024X768_60P:1;/*3*/
-+ uint32_t VESA_1152X864_30P:1;/*4*/
-+ uint32_t VESA_1152X864_60P:1;/*5*/
-+ uint32_t VESA_1280X768_30P:1;/*6*/
-+ uint32_t VESA_1280X768_60P:1;/*7*/
-+ uint32_t VESA_1280X800_30P:1;/*8*/
-+ uint32_t VESA_1280X800_60P:1;/*9*/
-+ uint32_t VESA_1360X768_30P:1;/*10*/
-+ uint32_t VESA_1360X768_60P:1;/*11*/
-+ uint32_t VESA_1366X768_30P:1;/*12*/
-+ uint32_t VESA_1366X768_60P:1;/*13*/
-+ uint32_t VESA_1280X1024_30P:1;/*14*/
-+ uint32_t VESA_1280X1024_60P:1;/*15*/
-+ uint32_t VESA_1400X1050_30P:1;/*16*/
-+ uint32_t VESA_1400X1050_60P:1;/*17*/
-+ uint32_t VESA_1440X900_30P:1;/*18*/
-+ uint32_t VESA_1440X900_60P:1;/*19*/
-+ uint32_t VESA_1600X900_30P:1;/*20*/
-+ uint32_t VESA_1600X900_60P:1;/*21*/
-+ uint32_t VESA_1600X1200_30P:1;/*22*/
-+ uint32_t VESA_1600X1200_60P:1;/*23*/
-+ uint32_t VESA_1680X1024_30P:1;/*24*/
-+ uint32_t VESA_1680X1024_60P:1;/*25*/
-+ uint32_t VESA_1680X1050_30P:1;/*26*/
-+ uint32_t VESA_1680X1050_60P:1;/*27*/
-+ uint32_t VESA_1920X1200_30P:1;/*28*/
-+ uint32_t VESA_1920X1200_60P:1;/*29*/
-+ uint32_t RESERVED:2;/*[30-31]*/
-+ } flags;
-+ uint32_t raw;
-+};
-+
-+union dal_remote_display_hh_mode_bitmap {
-+ struct {
-+ uint32_t HH_800X480_30P:1;/*0*/
-+ uint32_t HH_800X480_60P:1;/*1*/
-+ uint32_t HH_854X480_30P:1;/*2*/
-+ uint32_t HH_854X480_60P:1;/*3*/
-+ uint32_t HH_864X480_30P:1;/*4*/
-+ uint32_t HH_864X480_60P:1;/*5*/
-+ uint32_t HH_640X360_30P:1;/*6*/
-+ uint32_t HH_640X360_60P:1;/*7*/
-+ uint32_t HH_960X540_30P:1;/*8*/
-+ uint32_t HH_960X540_60P:1;/*9*/
-+ uint32_t HH_848X480_30P:1;/*10*/
-+ uint32_t HH_848X480_60P:1;/*11*/
-+ uint32_t RESERVED:20;/*[12-31]*/
-+ } flags;
-+ uint32_t raw;
-+};
-+
-+union dal_remote_display_stereo_3d_mode_bitmap {
-+ struct {
-+ uint32_t STEREO_1920X1080_24P_TOP_AND_BOTTOM:1;/*0*/
-+ uint32_t STEREO_1280X720_60P_TOP_AND_BOTTOM:1;/*1*/
-+ uint32_t STEREO_1280X720_50P_TOP_AND_BOTTOM:1;/*2*/
-+ uint32_t STEREO_1920X1080_24X2P_FRAME_ALTERNATE:1;/*3*/
-+ uint32_t STEREO_1280X720_60X2P_FRAME_ALTERNATE:1;/*4*/
-+ uint32_t STEREO_1280X720_30X2P_FRAME_ALTERNATE:1;/*5*/
-+ uint32_t STEREO_1280X720_50X2P_FRAME_ALTERNATE:1;/*6*/
-+ uint32_t STEREO_1280X720_25X2P_FRAME_ALTERNATE:1;/*7*/
-+ uint32_t STEREO_1920X1080_24P_FRAME_PACKING:1;/* 8*/
-+ uint32_t STEREO_1280X720_60P_FRAME_PACKING:1;/* 9*/
-+ uint32_t STEREO_1280X720_30P_FRAME_PACKING:1;/*10*/
-+ uint32_t STEREO_1280X720_50P_FRAME_PACKING:1;/*11*/
-+ uint32_t STEREO_1280X720_25P_FRAME_PACKING:1;/*12*/
-+ uint32_t RESERVED:19; /*[13-31]*/
-+ } flags;
-+ uint32_t raw;
-+};
-+
-+union dal_remote_display_audio_bitmap {
-+ struct {
-+ uint32_t LPCM_44100HZ_16BITS_2_CHANNELS:1;/*0*/
-+ uint32_t LPCM_48000HZ_16BITS_2_CHANNELS:1;/*1*/
-+ uint32_t AAC_48000HZ_16BITS_2_CHANNELS:1;/*2*/
-+ uint32_t AAC_48000HZ_16BITS_4_CHANNELS:1;/*3*/
-+ uint32_t AAC_48000HZ_16BITS_6_CHANNELS:1;/*4*/
-+ uint32_t AAC_48000HZ_16BITS_8_CHANNELS:1;/*5*/
-+ uint32_t AC3_48000HZ_16BITS_2_CHANNELS:1;/*6*/
-+ uint32_t AC3_48000HZ_16BITS_4_CHANNELS:1;/*7*/
-+ uint32_t AC3_48000HZ_16BITS_6_CHANNELS:1;/*8*/
-+ uint32_t RESERVED:23;/*[9-31]*/
-+ } flags;
-+ uint32_t raw;
-+};
-+
-+struct dal_remote_display_receiver_capability {
-+ union dal_remote_display_cea_mode_bitmap cea_mode;
-+ union dal_remote_display_vesa_mode_bitmap vesa_mode;
-+ union dal_remote_display_hh_mode_bitmap hh_mode;
-+ union dal_remote_display_stereo_3d_mode_bitmap stereo_3d_mode;
-+ union dal_remote_display_audio_bitmap audio;
-+};
-+
-+#endif /* __DAL_TYPES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/dc_clock_generator_interface.h b/drivers/gpu/drm/amd/dal/include/dc_clock_generator_interface.h
-new file mode 100644
-index 0000000..b7fb9ff
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/dc_clock_generator_interface.h
-@@ -0,0 +1,77 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_CLOCK_GENERATOR_INTERFACE_H__
-+#define __DC_CLOCK_GENERATOR_INTERFACE_H__
-+
-+#include "grph_object_ctrl_defs.h"
-+#include "set_mode_types.h"
-+
-+/* Parameter for programming the DCCP_DISP_SLOW_SELECT*/
-+struct dccg_mapping_params {
-+ uint32_t controllers_num;
-+ enum controller_id *controllers;
-+};
-+
-+/* Parameters related to HW DeSpread of DP Reference Clock*/
-+struct dccg_dp_ref_clk_ds_params {
-+ struct {
-+ /* Flag for Enabled SS on DP Reference Clock*/
-+ bool SS_ENABLED:1;
-+ /* Flag for HW De Spread enabled
-+ * (if enabled SS on DP Reference Clock)*/
-+ bool DS_ENABLED:1;
-+ /* Flag for HW De Spread Calculations enabled for DS_DTO_INCR
-+ * and DS_DTO_MODULO (if 0 SW programs DS_DTO_INCR and
-+ * DS_DTO_MODULO)*/
-+ bool DS_CALCULATIONS:1;
-+ } flags;
-+ /*DP Reference clock SS percentage
-+ * (if enabled downspread on DP Reference Clock)*/
-+ uint32_t ss_percentage;
-+ /*DP Reference clock SS percentage Divider (1000 or 100)*/
-+ uint32_t ss_percentage_divider;
-+};
-+
-+struct dc_clock_generator;
-+
-+void dal_dc_clock_generator_destroy(struct dc_clock_generator **dc);
-+void dal_dc_clock_generator_set_display_pipe_mapping(
-+ struct dc_clock_generator *dc_clk_gen,
-+ struct dccg_mapping_params *params);
-+bool dal_dc_clock_generator_get_dp_ref_clk_ds_params(
-+ struct dc_clock_generator *dc_clk_gen,
-+ struct dccg_dp_ref_clk_ds_params *params);
-+bool dal_dc_clock_generator_enable_gtc_counter(
-+ struct dc_clock_generator *dc_clk_gen,
-+ uint32_t dprefclk);
-+void dal_dc_clock_generator_disable_gtc_counter(
-+ struct dc_clock_generator *dc_clk_gen);
-+void dal_dc_clock_generator_set_gtc_group_offset(
-+ struct dc_clock_generator *dc_clk_gen,
-+ enum gtc_group group_num,
-+ uint32_t offset);
-+
-+#endif /* __DC_CLOCK_GENERATOR_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/dcs_interface.h b/drivers/gpu/drm/amd/dal/include/dcs_interface.h
-new file mode 100644
-index 0000000..b3474cf
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/dcs_interface.h
-@@ -0,0 +1,351 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef __DAL_DCS_INTERFACE_H__
-+#define __DAL_DCS_INTERFACE_H__
-+
-+#include "dcs_types.h"
-+#include "grph_object_id.h"
-+
-+struct dal_context;
-+struct dcs;
-+struct ddc_service;
-+enum ddc_transaction_type;
-+enum ddc_result;
-+struct display_sink_capability;
-+enum dc_timing_3d_format;
-+
-+struct dcs_cea_audio_mode_list;
-+struct dcs_customized_mode_list;
-+
-+struct dcs_init_data {
-+ struct dal_context *dal;
-+ struct adapter_service *as;
-+ struct timing_service *ts;
-+ enum dcs_interface_type interface_type;
-+ struct graphics_object_id grph_obj_id;
-+};
-+
-+struct dcs_cea_audio_mode_list *dal_dcs_cea_audio_mode_list_create(
-+ uint32_t list_size);
-+
-+void dal_dcs_cea_audio_mode_list_destroy(
-+ struct dcs_cea_audio_mode_list **list);
-+
-+bool dal_dcs_cea_audio_mode_list_append(
-+ struct dcs_cea_audio_mode_list *list,
-+ struct cea_audio_mode *cea_audio_mode);
-+uint32_t dal_dcs_cea_audio_mode_list_get_count(
-+ const struct dcs_cea_audio_mode_list *list);
-+void dal_dcs_cea_audio_mode_list_clear(
-+ struct dcs_cea_audio_mode_list *list);
-+
-+struct cea_audio_mode *dal_dcs_cea_audio_mode_list_at_index(
-+ const struct dcs_cea_audio_mode_list *list,
-+ uint32_t index);
-+
-+struct dcs *dal_dcs_create(const struct dcs_init_data *init_data);
-+
-+void dal_dcs_destroy(struct dcs **dcs);
-+
-+enum edid_retrieve_status dal_dcs_retrieve_raw_edid(struct dcs *dcs);
-+
-+uint32_t dal_dcs_get_edid_raw_data_size(struct dcs *dcs);
-+
-+enum edid_retrieve_status dal_dcs_override_raw_edid(
-+ struct dcs *dcs,
-+ uint32_t len,
-+ uint8_t *data);
-+
-+const uint8_t *dal_dcs_get_edid_raw_data(
-+ struct dcs *dcs,
-+ uint32_t *buff_size);
-+
-+enum edid_retrieve_status dal_dcs_update_edid_from_last_retrieved(
-+ struct dcs *dcs);
-+
-+/*Update DDC Service. returns the old DdcService being replaced*/
-+struct ddc_service *dal_dcs_update_ddc(
-+ struct dcs *dcs,
-+ struct ddc_service *ddc);
-+
-+void dal_dcs_set_transaction_type(
-+ struct dcs *dcs,
-+ enum ddc_transaction_type type);
-+
-+/*updates the ModeTimingList of given path with
-+ModeTiming reported by this DCS*/
-+void dal_dcs_update_ts_timing_list_on_display(
-+ struct dcs *dcs,
-+ uint32_t display_index);
-+
-+/* DDC query on generic slave address*/
-+bool dal_dcs_query_ddc_data(
-+ struct dcs *dcs,
-+ uint32_t address,
-+ uint8_t *write_buf,
-+ uint32_t write_buff_size,
-+ uint8_t *read_buff,
-+ uint32_t read_buff_size);
-+
-+bool dal_dcs_get_vendor_product_id_info(
-+ struct dcs *dcs,
-+ struct vendor_product_id_info *info);
-+
-+bool dal_dcs_get_display_name(struct dcs *dcs, uint8_t *name, uint32_t size);
-+
-+bool dal_dcs_get_display_characteristics(
-+ struct dcs *dcs,
-+ struct display_characteristics *characteristics);
-+
-+bool dal_dcs_get_screen_info(
-+ struct dcs *dcs,
-+ struct edid_screen_info *info);
-+
-+enum dcs_edid_connector_type dal_dcs_get_connector_type(struct dcs *dcs);
-+
-+bool dal_dcs_get_display_pixel_encoding(
-+ struct dcs *dcs,
-+ struct display_pixel_encoding_support *pe);
-+
-+enum display_dongle_type dal_dcs_get_dongle_type(struct dcs *dcs);
-+
-+void dal_dcs_query_sink_capability(
-+ struct dcs *dcs,
-+ struct display_sink_capability *sink_cap,
-+ bool hpd_sense_bit);
-+
-+void dal_dcs_reset_sink_capability(struct dcs *dcs);
-+
-+bool dal_dcs_get_sink_capability(
-+ struct dcs *dcs,
-+ struct display_sink_capability *sink_cap);
-+
-+bool dal_dcs_emulate_sink_capability(
-+ struct dcs *dcs,
-+ struct display_sink_capability *sink_cap);
-+
-+bool dal_dcs_get_display_color_depth(
-+ struct dcs *dcs,
-+ struct display_color_depth_support *color_depth);
-+
-+bool dal_dcs_get_display_pixel_encoding(
-+ struct dcs *dcs,
-+ struct display_pixel_encoding_support *pixel_encoding);
-+
-+bool dal_dcs_get_cea861_support(
-+ struct dcs *dcs,
-+ struct cea861_support *cea861_support);
-+
-+bool dal_dcs_get_cea_vendor_specific_data_block(
-+ struct dcs *dcs,
-+ struct cea_vendor_specific_data_block *vendor_block);
-+
-+bool dal_dcs_get_cea_speaker_allocation_data_block(
-+ struct dcs *dcs,
-+ enum signal_type signal,
-+ union cea_speaker_allocation_data_block *spkr_data);
-+
-+bool dal_dcs_get_cea_colorimetry_data_block(
-+ struct dcs *dcs,
-+ struct cea_colorimetry_data_block *colorimetry_data_block);
-+
-+bool dal_dcs_get_cea_video_capability_data_block(
-+ struct dcs *dcs,
-+ union cea_video_capability_data_block *video_capability_data_block);
-+
-+uint32_t dal_dcs_get_extensions_num(struct dcs *dcs);
-+
-+const struct dcs_cea_audio_mode_list *dal_dcs_get_cea_audio_modes(
-+ struct dcs *dcs,
-+ enum signal_type signal);
-+
-+bool dal_dcs_is_audio_supported(struct dcs *dcs);
-+
-+bool dal_dcs_validate_customized_mode(
-+ struct dcs *dcs,
-+ const struct dcs_customized_mode *customized_mode);
-+
-+bool dal_dcs_add_customized_mode(
-+ struct dcs *dcs,
-+ struct dcs_customized_mode *customized_mode);
-+
-+bool dal_dcs_delete_customized_mode(struct dcs *dcs, uint32_t index);
-+
-+const struct dcs_customized_mode_list *dal_dcs_get_customized_modes(
-+ struct dcs *dcs);
-+
-+bool dal_dcs_delete_mode_timing_override(
-+ struct dcs *dcs,
-+ struct dcs_override_mode_timing *dcs_mode_timing);
-+
-+bool dal_dcs_set_mode_timing_override(
-+ struct dcs *dcs,
-+ uint32_t display_index,
-+ struct dcs_override_mode_timing *dcs_mode_timing);
-+
-+bool dal_dcs_get_timing_override_for_mode(
-+ struct dcs *dcs,
-+ uint32_t display_index,
-+ struct dc_mode_info *mode_info,
-+ struct dcs_override_mode_timing_list *dcs_mode_timing_list);
-+
-+uint32_t dal_dcs_get_num_mode_timing_overrides(struct dcs *dcs);
-+
-+bool dal_dcs_get_timing_override_list(
-+ struct dcs *dcs,
-+ uint32_t display_index,
-+ struct dcs_override_mode_timing_list *dcs_mode_timing_list,
-+ uint32_t size);
-+
-+bool dal_dcs_get_supported_force_hdtv_mode(
-+ struct dcs *dcs,
-+ union hdtv_mode_support *hdtv_mode);
-+
-+bool dal_dcs_get_user_force_hdtv_mode(
-+ struct dcs *dcs,
-+ union hdtv_mode_support *hdtv_mode);
-+
-+bool dal_dcs_set_user_force_hdtv_mode(
-+ struct dcs *dcs,
-+ const union hdtv_mode_support *hdtv_mode);
-+
-+bool dal_dcs_get_fid9204_allow_ce_mode_only_option(
-+ struct dcs *dcs,
-+ bool is_hdmi,
-+ bool *enable);
-+
-+bool dal_dcs_set_fid9204_allow_ce_mode_only_option(
-+ struct dcs *dcs,
-+ bool is_hdmi,
-+ bool enable);
-+
-+bool dal_dcs_get_panel_misc_info(
-+ struct dcs *dcs,
-+ union panel_misc_info *panel_info);
-+
-+enum ddc_result dal_dcs_dpcd_read(
-+ struct dcs *dcs,
-+ uint32_t address,
-+ uint8_t *buffer,
-+ uint32_t length);
-+
-+enum ddc_result dal_dcs_dpcd_write(
-+ struct dcs *dcs,
-+ uint32_t address,
-+ const uint8_t *buffer,
-+ uint32_t length);
-+
-+bool dal_dcs_get_range_limit(
-+ struct dcs *dcs,
-+ struct display_range_limits *limit);
-+
-+bool dal_dcs_set_range_limit_override(
-+ struct dcs *dcs,
-+ struct display_range_limits *limit);
-+
-+bool dal_dcs_get_user_select_limit(
-+ struct dcs *dcs,
-+ struct monitor_user_select_limits *limit);
-+
-+bool dal_dcs_set_user_select_limit(
-+ struct dcs *dcs,
-+ struct monitor_user_select_limits *limit);
-+
-+bool dal_dcs_get_dongle_mode_support(
-+ struct dcs *dcs,
-+ union hdtv_mode_support *hdtv_mode);
-+
-+bool dal_dcs_get_timing_limits(
-+ struct dcs *dcs,
-+ struct timing_limits *timing_limits);
-+
-+bool dal_dcs_get_drr_config(
-+ struct dcs *dcs,
-+ struct drr_config *config);
-+
-+bool dal_dcs_force_dp_audio(struct dcs *dcs, bool force_audio_on);
-+
-+bool dal_dcs_is_dp_audio_forced(struct dcs *dcs);
-+
-+const struct monitor_patch_info *dal_dcs_get_monitor_patch_info(
-+ struct dcs *dcs,
-+ enum monitor_patch_type patch_type);
-+
-+bool dal_dcs_set_monitor_patch_info(
-+ struct dcs *dcs,
-+ struct monitor_patch_info *patch_info);
-+
-+union dcs_monitor_patch_flags dal_dcs_get_monitor_patch_flags(struct dcs *dcs);
-+
-+enum dcs_packed_pixel_format dal_dcs_get_enabled_packed_pixel_format(
-+ struct dcs *dcs);
-+
-+enum dcs_packed_pixel_format dal_dcs_get_monitor_packed_pixel_format(
-+ struct dcs *dcs);
-+
-+bool dal_dcs_report_single_selected_timing(struct dcs *dcs);
-+
-+bool dal_dcs_can_tile_scale(struct dcs *dcs);
-+
-+void dal_dcs_set_single_selected_timing_restriction(
-+ struct dcs *dcs,
-+ bool value);
-+
-+const struct dcs_edid_supported_max_bw *dal_dcs_get_edid_supported_max_bw(
-+ struct dcs *dcs);
-+
-+bool dal_dcs_is_non_continous_frequency(struct dcs *dcs);
-+
-+struct dcs_stereo_3d_features dal_dcs_get_stereo_3d_features(
-+ struct dcs *dcs,
-+ enum dc_timing_3d_format format);
-+
-+union stereo_3d_support dal_dcs_get_stereo_3d_support(struct dcs *dcs);
-+
-+void dal_dcs_override_stereo_3d_support(
-+ struct dcs *dcs,
-+ union stereo_3d_support support);
-+
-+void dal_dcs_set_remote_display_receiver_capabilities(
-+ struct dcs *dcs,
-+ const struct dal_remote_display_receiver_capability *cap);
-+
-+void dal_dcs_clear_remote_display_receiver_capabilities(struct dcs *dcs);
-+
-+bool dal_dcs_get_display_tile_info(
-+ struct dcs *dcs,
-+ struct dcs_display_tile *display_tile,
-+ bool first_display);
-+
-+bool dal_dcs_get_container_id(struct dcs *dcs,
-+ struct dcs_container_id *container_id);
-+
-+bool dal_dcs_set_container_id(struct dcs *dcs,
-+ struct dcs_container_id *container_id);
-+
-+void dal_dcs_invalidate_container_id(struct dcs *dcs);
-+
-+union dcs_monitor_patch_flags dal_dcs_get_monitor_patch_flags(struct dcs *dcs);
-+
-+#endif /* __DAL_DCS_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/dcs_types.h b/drivers/gpu/drm/amd/dal/include/dcs_types.h
-new file mode 100644
-index 0000000..8c65057
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/dcs_types.h
-@@ -0,0 +1,742 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DCS_TYPES_H__
-+#define __DAL_DCS_TYPES_H__
-+
-+#include "signal_types.h"
-+
-+#include "dc_types.h"
-+
-+#define NUM_OF_BYTE_EDID_COLOR_CHARACTERISTICS 10
-+#define MAX_NUMBER_OF_HDMI_VSDB_3D_EXTENDED_SUPPORT 21
-+#define MAX_NUMBER_OF_HDMI_VSDB_VICS 7
-+
-+struct drr_config {
-+ /* minimum frame per second for dynamic
-+ * refresh rate feature; 0 if drr support not found*/
-+ uint32_t min_fps_in_microhz;
-+ bool force_lock_on_event;
-+ bool lock_to_master_vsync;
-+
-+ struct {
-+ uint8_t FORCED_BY_REGKEY_OR_ESCAPE:1;
-+ uint8_t FORCED_BY_VBIOS:1;
-+ uint8_t SUPPORTED_BY_EDID:1;
-+ } support_method;
-+};
-+
-+struct timing_limits {
-+ uint32_t min_pixel_clock_in_khz;
-+ uint32_t max_pixel_clock_in_khz;
-+};
-+
-+struct vendor_product_id_info {
-+ uint32_t manufacturer_id;
-+ uint32_t product_id;
-+ uint32_t serial_id;
-+ uint32_t manufacture_week;
-+ uint32_t manufacture_year;
-+};
-+
-+struct display_range_limits {
-+ uint32_t min_v_rate_hz;
-+ uint32_t max_v_rate_hz;
-+ uint32_t min_h_rate_khz;
-+ uint32_t max_h_rateIn_khz;
-+ uint32_t max_pix_clk_khz;
-+ bool use_override;
-+};
-+
-+struct monitor_user_select_limits {
-+ bool use_ati_override;
-+ uint32_t max_h_res;
-+ uint32_t max_v_res;
-+ uint32_t max_refresh_rate;
-+};
-+
-+enum edid_screen_aspect_ratio {
-+ EDID_SCREEN_AR_UNKNOWN = 0,
-+ EDID_SCREEN_AR_PROJECTOR,
-+ EDID_SCREEN_AR_16X9,
-+ EDID_SCREEN_AR_16X10,
-+ EDID_SCREEN_AR_4X3,
-+ EDID_SCREEN_AR_5X4,
-+ EDID_SCREEN_AR_9X16,
-+ EDID_SCREEN_AR_10X16,
-+ EDID_SCREEN_AR_3X4,
-+ EDID_SCREEN_AR_4X5
-+};
-+
-+struct edid_screen_info {
-+ enum edid_screen_aspect_ratio aspect_ratio;
-+ uint32_t width;
-+ uint32_t height;
-+};
-+
-+struct display_characteristics {
-+ uint8_t gamma;
-+ uint8_t color_characteristics[NUM_OF_BYTE_EDID_COLOR_CHARACTERISTICS];
-+};
-+
-+union cv_smart_dongle_modes {
-+ uint8_t all;
-+ struct cv_smart_dongle_switches {
-+ uint8_t MODE_1080I:1;
-+ uint8_t MODE_720P:1;
-+ uint8_t MODE_540P:1;
-+ uint8_t MODE_480P:1;
-+ uint8_t MODE_480I:1;
-+ uint8_t MODE_16_9:1;
-+ } switches;
-+};
-+
-+struct cea_audio_mode {
-+ uint8_t format_code; /* ucData[0] [6:3]*/
-+ uint8_t channel_count; /* ucData[0] [2:0]*/
-+ uint8_t sample_rate; /* ucData[1]*/
-+ union {
-+ uint8_t sample_size; /* for LPCM*/
-+ /* for Audio Formats 2-8 (Max bit rate divided by 8 kHz)*/
-+ uint8_t max_bit_rate;
-+ uint8_t audio_codec_vendor_specific; /* for Audio Formats 9-15*/
-+ };
-+};
-+
-+union cea_speaker_allocation_data_block {
-+ struct {
-+ uint32_t FL_FR:1;
-+ uint32_t LFE:1;
-+ uint32_t FC:1;
-+ uint32_t RL_RR:1;
-+ uint32_t RC:1;
-+ uint32_t FLC_FRC:1;
-+ uint32_t RLC_RRC:1;
-+ } bits;
-+ uint32_t raw;
-+};
-+
-+struct cea_colorimetry_data_block {
-+ struct {
-+ uint32_t XV_YCC601:1;
-+ uint32_t XV_YCC709:1;
-+ uint32_t S_YCC601:1;
-+ uint32_t ADOBE_YCC601:1;
-+ uint32_t ADOBE_RGB:1;
-+
-+ } flag;
-+ struct {
-+ uint32_t MD0:1;
-+ uint32_t MD1:1;
-+ uint32_t MD2:1;
-+ uint32_t MD3:1;
-+ } metadata_flag;
-+};
-+
-+union cea_video_capability_data_block {
-+ struct {
-+ uint8_t S_CE0:1;
-+ uint8_t S_CE1:1;
-+ uint8_t S_IT0:1;
-+ uint8_t S_IT1:1;
-+ uint8_t S_PT0:1;
-+ uint8_t S_PT1:1;
-+ uint8_t QS:1;
-+ uint8_t QY:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+enum stereo_3d_multi_presence {
-+ STEREO_3D_MULTI_NOT_PRESENT = 0,
-+ STEREO_3D_MULTI_ALL_FORMATS,
-+ STEREO_3D_MULTI_MASKED_FORMATS,
-+ STEREO_3D_MULTI_RESERVED
-+};
-+
-+enum cea_hdmi_vic {
-+ CEA_HDMI_VIC_RESERVED = 0,
-+ CEA_HDMI_VIC_4KX2K_30,
-+ CEA_HDMI_VIC_4KX2K_25,
-+ CEA_HDMI_VIC_4KX2K_24,
-+ CEA_HDMI_VIC_4KX2K_24_SMPTE
-+};
-+
-+struct cea_hdmi_vsdb_extended_caps {
-+ uint32_t reserved;
-+ uint32_t image_size;
-+ enum stereo_3d_multi_presence stereo_3d_multi_present;
-+ bool stereo_3d_present;
-+ uint32_t hdmi_3d_len;
-+ uint32_t hdmi_vic_len;
-+};
-+
-+struct cea_vendor_specific_data_block {
-+
-+ uint32_t ieee_id;
-+
-+ struct commonent_phy {
-+ uint32_t PHY_ADDR_A:4;
-+ uint32_t PHY_ADDR_B:4;
-+ uint32_t PHY_ADDR_C:4;
-+ uint32_t PHY_ADDR_D:4;
-+ } commonent_phy_addr;
-+
-+ struct byte6 {
-+ uint32_t SUPPORTS_AI:1;
-+ uint32_t DC_48BIT:1;
-+ uint32_t DC_36BIT:1;
-+ uint32_t DC_30BIT:1;
-+ uint32_t DC_Y444:1;
-+ uint32_t DVI_DUAL:1;
-+ uint32_t RESERVED:2;
-+ } byte6;/* link capabilities*/
-+ bool byte6_valid;
-+
-+ uint32_t max_tmds_clk_mhz;
-+
-+ struct byte8 {
-+ uint32_t LATENCY_FIELDS_PRESENT:1;
-+ uint32_t ILATENCY_FIELDS_PRESENT:1;
-+ uint32_t HDMI_VIDEO_PRESENT:1;
-+ uint32_t RESERVED:1;
-+ uint32_t CNC3_GAME:1;
-+ uint32_t CNC2_CINEMA:1;
-+ uint32_t CNC1_PHOTO:1;
-+ uint32_t CNC0_GRAPHICS:1;
-+ } byte8;
-+ /*bit 6-7: latency flags to indicate valid latency fields*/
-+ /*bit 5: support of additional video format capabilities*/
-+ /* bit 0-3: flags indicating which content type is supported*/
-+ uint32_t video_latency;
-+ uint32_t audio_latency;
-+ uint32_t i_video_latency;
-+ uint32_t i_audio_latency;
-+
-+ struct cea_hdmi_vsdb_extended_caps hdmi_vsdb_extended_caps;
-+
-+ enum stereo_3d_multi_presence stereo_3d_multi_present;
-+
-+ struct {
-+ bool FRAME_PACKING:1;
-+ bool SIDE_BY_SIDE_HALF:1;
-+ bool TOP_AND_BOTTOM:1;
-+ } stereo_3d_all_support;
-+ uint16_t stereo_3d_mask;
-+
-+ enum cea_hdmi_vic hdmi_vic[MAX_NUMBER_OF_HDMI_VSDB_VICS];
-+ struct stereo_3d_extended_support {
-+ struct {
-+ bool FRAME_PACKING:1;
-+ bool SIDE_BY_SIDE_HALF:1;
-+ bool TOP_AND_BOTTOM:1;
-+ } format;
-+ uint32_t vic_index;
-+ uint32_t value;
-+ uint32_t size;
-+ } stereo_3d_extended_support[MAX_NUMBER_OF_HDMI_VSDB_3D_EXTENDED_SUPPORT];
-+};
-+
-+struct cea861_support {
-+
-+ uint32_t revision;
-+ union {
-+ struct {
-+ uint32_t NATIVE_COUNT:4;
-+ uint32_t BASE_AUDIO:1;
-+ uint32_t YCRCB444:1;
-+ uint32_t YCRCB422:1;
-+ uint32_t UNDER_SCAN:1;
-+ } features;
-+ uint8_t raw_features;
-+ };
-+};
-+
-+struct dcs_customized_mode {
-+ struct {
-+ uint32_t READ_ONLY:1;
-+ uint32_t ADD_BY_DRIVER:1;
-+ uint32_t INTERLACED:1;
-+ uint32_t BASE_MODE:1;
-+ } flags;
-+ struct dc_mode_info base_mode_info;
-+ struct dc_mode_info customized_mode_info;
-+};
-+
-+struct dcs_override_mode_timing {
-+ /* possible timing standards, bit vector of TimingStandard*/
-+ uint32_t possible_timing_standards;
-+ /* indicate driver default timing is used , no override*/
-+ bool use_driver_default_timing;
-+ struct dc_mode_timing mode_timing;
-+};
-+
-+struct dcs_override_mode_timing_list {
-+ uint32_t max_num_overrides;
-+ uint32_t num_overrides;
-+ struct dcs_override_mode_timing mode_timings[1];
-+};
-+
-+/* "interface type" is different from Signal Type because
-+ * an "interface type" can be driven by more than one Signal Type.
-+ * For example, INTERFACE_TYPE_DVI can be driven by
-+ * Single or Dual link DVI signal. */
-+enum dcs_interface_type {
-+ INTERFACE_TYPE_VGA = 0,
-+ INTERFACE_TYPE_DVI,
-+ INTERFACE_TYPE_CV,
-+ INTERFACE_TYPE_TV,
-+ INTERFACE_TYPE_LVDS,
-+ INTERFACE_TYPE_DP,
-+ INTERFACE_TYPE_WIRELESS,
-+ INTERFACE_TYPE_CF,
-+ INTERFACE_TYPE_EDP
-+};
-+
-+
-+union panel_misc_info {
-+ struct {
-+ uint32_t H_CUT_OFF:1;
-+ uint32_t H_SYNC_POLARITY:1;/*0=Active High, 1=Active Low*/
-+ uint32_t V_SYNC_POLARITY:1; /*0=Active High, 1=Active Low*/
-+ uint32_t V_CUT_OFF:1;
-+ uint32_t H_REPLICATION_BY_2:1;
-+ uint32_t V_REPLICATION_BY_2:1;
-+ uint32_t COMPOSITE_SYNC:1;
-+ uint32_t INTERLACE:1;
-+ uint32_t DOUBLE_CLOCK:1;
-+ uint32_t RGB888:1;
-+ uint32_t GREY_LEVEL:2;
-+ uint32_t SPATIAL:1;
-+ uint32_t TEMPORAL:1;
-+ uint32_t API_ENABLED:1;
-+ } bits;
-+ uint32_t raw;
-+};
-+
-+union hdtv_mode_support {
-+ struct {
-+ uint32_t HDTV_SUPPORT_480I:1;
-+ uint32_t HDTV_SUPPORT_480P:1;
-+ uint32_t HDTV_SUPPORT_576I25:1;
-+ uint32_t HDTV_SUPPORT_576P50:1;
-+ uint32_t HDTV_SUPPORT_720P:1;
-+ uint32_t HDTV_SUPPORT_720P50:1;
-+ uint32_t HDTV_SUPPORT_1080I:1;
-+ uint32_t HDTV_SUPPORT_1080I25:1;
-+ uint32_t HDTV_SUPPORT_1080P:1;
-+ uint32_t HDTV_SUPPORT_1080P50:1;
-+ uint32_t HDTV_SUPPORT_1080P24:1;
-+ uint32_t HDTV_SUPPORT_1080P25:1;
-+ uint32_t HDTV_SUPPORT_1080P30:1;
-+ uint32_t HDTV_SUPPORT_16X9:1;
-+ } bits;
-+ uint32_t raw;
-+};
-+
-+enum edid_retrieve_status {
-+ EDID_RETRIEVE_SUCCESS = 0,
-+ EDID_RETRIEVE_FAIL,
-+ EDID_RETRIEVE_SAME_EDID,
-+ EDID_RETRIEVE_FAIL_WITH_PREVIOUS_SUCCESS
-+};
-+
-+#define DCS_DECODE_EDID_RETRIEVE_STATUS(status) \
-+ (status == EDID_RETRIEVE_SUCCESS) ? "EDID_RETRIEVE_SUCCESS" : \
-+ (status == EDID_RETRIEVE_FAIL) ? "EDID_RETRIEVE_FAIL" : \
-+ (status == EDID_RETRIEVE_SAME_EDID) ? "EDID_RETRIEVE_SAME_EDID" : \
-+ (status == EDID_RETRIEVE_FAIL_WITH_PREVIOUS_SUCCESS) ? \
-+ "EDID_RETRIEVE_FAIL_WITH_PREVIOUS_SUCCESS" : "Unknown"
-+
-+
-+#ifndef TV_SIGNALFORMAT_DEFINED
-+#define TV_SIGNALFORMAT_DEFINED
-+enum tv_signal_format {
-+ TV_SIGNAL_FORMAT_UNKNOWN,
-+ TV_SIGNAL_FORMAT_NTSC,
-+ TV_SIGNAL_FORMAT_NTSC_J,
-+ TV_SIGNAL_FORMAT_PAL,
-+ TV_SIGNAL_FORMAT_PAL_M,
-+ TV_SIGNAL_FORMAT_PAL_CN,
-+ TV_SIGNAL_FORMAT_SECAM
-+};
-+#endif
-+
-+enum tv_signal_format_result {
-+ TV_SIGNAL_FORMAT_RESULT_OK,
-+ TV_SIGNAL_FORMAT_SET_MODE_REQ,
-+ TV_SIGNAL_FORMAT_REBOOT_REQ,
-+ TV_SIGNAL_FORMAT_ERROR
-+};
-+
-+enum pixel_encoding_mask {
-+ PIXEL_ENCODING_MASK_YCBCR444 = 0x01,
-+ PIXEL_ENCODING_MASK_YCBCR422 = 0x02,
-+ PIXEL_ENCODING_MASK_RGB = 0x04,
-+};
-+
-+struct display_pixel_encoding_support {
-+ uint32_t mask;
-+};
-+
-+enum color_depth_index {
-+ COLOR_DEPTH_INDEX_UNKNOWN,
-+ COLOR_DEPTH_INDEX_666 = 0x01,
-+ COLOR_DEPTH_INDEX_888 = 0x02,
-+ COLOR_DEPTH_INDEX_101010 = 0x04,
-+ COLOR_DEPTH_INDEX_121212 = 0x08,
-+ COLOR_DEPTH_INDEX_141414 = 0x10,
-+ COLOR_DEPTH_INDEX_161616 = 0x20,
-+ COLOR_DEPTH_INDEX_LAST = 0x40,
-+};
-+
-+struct display_color_depth_support {
-+ uint32_t mask;
-+ bool deep_color_native_res_only;
-+};
-+
-+struct display_color_and_pixel_support {
-+ struct display_color_depth_support color_depth_support;
-+ struct display_pixel_encoding_support pixel_encoding_support;
-+ bool deep_color_y444_support;
-+};
-+
-+enum dcs_packed_pixel_format {
-+ DCS_PACKED_PIXEL_FORMAT_NOT_PACKED = 0,
-+ DCS_PACKED_PIXEL_FORMAT_SPLIT_G70_B54_R70_B10 = 1,
-+ DCS_PACKED_PIXEL_FORMAT_R70_G76 = 2,
-+ DCS_PACKED_PIXEL_FORMAT_SPLIT_B70_G10_R70_G76 = 3,
-+ DCS_PACKED_PIXEL_FORMAT_G70_B54_R70_B10 = 4,
-+ DCS_PACKED_PIXEL_FORMAT_G70_B54 = 5,
-+ DCS_PACKED_PIXEL_FORMAT_B70_R30_G70_R74 = 6,
-+ DCS_PACKED_PIXEL_FORMAT_B70_G70_R70 = 7,
-+ DCS_PACKED_PIXEL_FORMAT_B70_R32_G70_R76 = 8,
-+};
-+
-+enum monitor_manufacturer_id {
-+ MONITOR_MANUFACTURER_ID_0 = 0x0000,
-+ MONITOR_MANUFACTURER_ID_1 = 0x3834,
-+ MONITOR_MANUFACTURER_ID_2 = 0x4d24,
-+ MONITOR_MANUFACTURER_ID_3 = 0x293E,
-+ MONITOR_MANUFACTURER_ID_4 = 0x635a,
-+ MONITOR_MANUFACTURER_ID_5 = 0x1006,
-+ MONITOR_MANUFACTURER_ID_6 = 0xc32a,
-+ MONITOR_MANUFACTURER_ID_7 = 0x4d24,
-+ MONITOR_MANUFACTURER_ID_8 = 0x110e,
-+ MONITOR_MANUFACTURER_ID_9 = 0xaf0d,
-+ MONITOR_MANUFACTURER_ID_10 = 0x6D1E,
-+ MONITOR_MANUFACTURER_ID_11 = 0xA338,
-+ MONITOR_MANUFACTURER_ID_12 = 0xC315,
-+ MONITOR_MANUFACTURER_ID_13 = 0xD94D,
-+ MONITOR_MANUFACTURER_ID_14 = 0x104D,
-+ MONITOR_MANUFACTURER_ID_15 = 0x855C,
-+ MONITOR_MANUFACTURER_ID_16 = 0x4251,
-+ MONITOR_MANUFACTURER_ID_17 = 0xA934,
-+ MONITOR_MANUFACTURER_ID_18 = 0x0C41,
-+ /* TODO: Update when EDID is available */
-+ MONITOR_MANUFACTURER_ID_19 = 0xDEAD,
-+ MONITOR_MANUFACTURER_ID_20 = 0x6904,
-+ MONITOR_MANUFACTURER_ID_21 = 0xAC10,
-+ MONITOR_MANUFACTURER_ID_22 = 0x2D4C,
-+ MONITOR_MANUFACTURER_ID_23 = 0x144E,
-+ MONITOR_MANUFACTURER_ID_24 = 0x6c50,
-+ MONITOR_MANUFACTURER_ID_26 = 0x0c41,
-+ MONITOR_MANUFACTURER_ID_27 = 0x143E,
-+ MONITOR_MANUFACTURER_ID_25 = 0xffff,
-+ MONITOR_MANUFACTURER_ID_28 = 0x3421,
-+ MONITOR_MANUFACTURER_ID_29 = 0x2D19,
-+ MONITOR_MANUFACTURER_ID_30 = 0x8B52,
-+ MONITOR_MANUFACTURER_ID_31 = 0x7204,
-+ MONITOR_MANUFACTURER_ID_32 = 0xF022,
-+ MONITOR_MANUFACTURER_ID_33 = 0x0E11,
-+ MONITOR_MANUFACTURER_ID_34 = 0xD241,
-+ MONITOR_MANUFACTURER_ID_35 = 0xAE30,
-+ MONITOR_MANUFACTURER_ID_36 = 0xF91E,
-+ MONITOR_MANUFACTURER_ID_37 = 0xAB4C,
-+};
-+
-+enum monitor_product_id {
-+ MONITOR_PRODUCT_ID_0 = 0x0000,
-+ MONITOR_PRODUCT_ID_1 = 0x0BCC,
-+ MONITOR_PRODUCT_ID_2 = 0x251F,
-+ MONITOR_PRODUCT_ID_3 = 0x5241,
-+ MONITOR_PRODUCT_ID_4 = 0x6919,
-+ MONITOR_PRODUCT_ID_5 = 0xee18,
-+ MONITOR_PRODUCT_ID_6 = 0xf008,
-+ MONITOR_PRODUCT_ID_7 = 0x2f0c,
-+ MONITOR_PRODUCT_ID_7_2 = 0x3411,
-+ MONITOR_PRODUCT_ID_9 = 0x4208,
-+ MONITOR_PRODUCT_ID_10 = 0xE51D,
-+ MONITOR_PRODUCT_ID_11 = 0x7E22,
-+ MONITOR_PRODUCT_ID_12 = 0x0E23,
-+ MONITOR_PRODUCT_ID_13 = 0x9d08,
-+ MONITOR_PRODUCT_ID_14 = 0x9236,
-+ MONITOR_PRODUCT_ID_15 = 0x9227,
-+ MONITOR_PRODUCT_ID_16 = 0x0220,
-+ MONITOR_PRODUCT_ID_17 = 0x4920,
-+ MONITOR_PRODUCT_ID_18 = 0x251f,
-+ MONITOR_PRODUCT_ID_19 = 0x1395,
-+ MONITOR_PRODUCT_ID_20 = 0xc04e,
-+ MONITOR_PRODUCT_ID_21 = 0x5787,
-+ MONITOR_PRODUCT_ID_22 = 0x5A71,
-+ MONITOR_PRODUCT_ID_23 = 0x6622,
-+ MONITOR_PRODUCT_ID_24 = 0x20C1,
-+ MONITOR_PRODUCT_ID_25 = 0x2110,
-+ MONITOR_PRODUCT_ID_26 = 0x2006,
-+ MONITOR_PRODUCT_ID_27 = 0x1827,
-+ MONITOR_PRODUCT_ID_28 = 0x0EA0,
-+ MONITOR_PRODUCT_ID_29 = 0x03D0,
-+ MONITOR_PRODUCT_ID_30 = 0x01D2,
-+ MONITOR_PRODUCT_ID_31 = 0x2801,
-+ MONITOR_PRODUCT_ID_32 = 0x0FB3,
-+ MONITOR_PRODUCT_ID_33 = 0x0FB1,
-+ MONITOR_PRODUCT_ID_34 = 0xA045,
-+ MONITOR_PRODUCT_ID_35 = 0x0001,
-+ MONITOR_PRODUCT_ID_36 = 0xA296,
-+ MONITOR_PRODUCT_ID_38 = 0x21DC,
-+ MONITOR_PRODUCT_ID_37 = 0x21EA,
-+ MONITOR_PRODUCT_ID_39 = 0x4093,
-+ MONITOR_PRODUCT_ID_40 = 0x4094,
-+ MONITOR_PRODUCT_ID_41 = 0x4094,
-+ MONITOR_PRODUCT_ID_42 = 0x32A2,
-+ MONITOR_PRODUCT_ID_43 = 0xE009,
-+ MONITOR_PRODUCT_ID_44 = 0xA010,
-+ MONITOR_PRODUCT_ID_45 = 0x405C,
-+ MONITOR_PRODUCT_ID_46 = 0xF017,
-+ MONITOR_PRODUCT_ID_47 = 0xD026,
-+ MONITOR_PRODUCT_ID_48 = 0x4036,
-+ MONITOR_PRODUCT_ID_49 = 0x4065,
-+ MONITOR_PRODUCT_ID_50 = 0xA02A,
-+ MONITOR_PRODUCT_ID_51 = 0xA02C,
-+ MONITOR_PRODUCT_ID_46_HDMI = 0xF016,
-+ MONITOR_PRODUCT_ID_53 = 0xF048,
-+ MONITOR_PRODUCT_ID_54 = 0xA0A2,
-+ MONITOR_PRODUCT_ID_55 = 0x4083,
-+ MONITOR_PRODUCT_ID_56 = 0x0E74,
-+ MONITOR_PRODUCT_ID_57 = 0x2771,
-+ MONITOR_PRODUCT_ID_58 = 0x0814,
-+ MONITOR_PRODUCT_ID_59 = 0xffff,
-+ MONITOR_PRODUCT_ID_60 = 0x3339,
-+ MONITOR_PRODUCT_ID_61 = 0x01F5,
-+ MONITOR_PRODUCT_ID_62 = 0x02A5,
-+ MONITOR_PRODUCT_ID_63 = 0x06AC,
-+ MONITOR_PRODUCT_ID_64 = 0x04D5,
-+ MONITOR_PRODUCT_ID_65 = 0x079D,
-+ MONITOR_PRODUCT_ID_66 = 0x079F,
-+ MONITOR_PRODUCT_ID_67 = 0x0797,
-+ MONITOR_PRODUCT_ID_68 = 0x0B80,
-+ MONITOR_PRODUCT_ID_69 = 0x7D06,
-+ MONITOR_PRODUCT_ID_70 = 0x0131,
-+ MONITOR_PRODUCT_ID_71 = 0x8545,
-+ MONITOR_PRODUCT_ID_72 = 0x0002,
-+ MONITOR_PRODUCT_ID_73 = 0x0125,
-+ MONITOR_PRODUCT_ID_74 = 0x00D0,
-+ MONITOR_PRODUCT_ID_75 = 0x26F7,
-+ MONITOR_PRODUCT_ID_76 = 0x26F9,
-+ MONITOR_PRODUCT_ID_77 = 0x2807,
-+ MONITOR_PRODUCT_ID_78 = 0x26F3,
-+ MONITOR_PRODUCT_ID_79 = 0x2676,
-+ MONITOR_PRODUCT_ID_80 = 0x0A72,
-+ MONITOR_PRODUCT_ID_81 = 0x2693,
-+ MONITOR_PRODUCT_ID_82 = 0x2615,
-+ MONITOR_PRODUCT_ID_83 = 0x2613,
-+ MONITOR_PRODUCT_ID_84 = 0x262D,
-+ MONITOR_PRODUCT_ID_85 = 0x264B,
-+ MONITOR_PRODUCT_ID_86 = 0x2869,
-+ MONITOR_PRODUCT_ID_87 = 0x286C,
-+ MONITOR_PRODUCT_ID_88 = 0x288F,
-+ MONITOR_PRODUCT_ID_89 = 0x2954,
-+ MONITOR_PRODUCT_ID_90 = 0x6522,
-+ MONITOR_PRODUCT_ID_91 = 0x0FAE,
-+ MONITOR_PRODUCT_ID_92 = 0x0A0C,
-+ MONITOR_PRODUCT_ID_93 = 0x00BF,
-+ MONITOR_PRODUCT_ID_94 = 0x0,
-+};
-+
-+enum monitor_patch_type {
-+ MONITOR_PATCH_TYPE_NONE,
-+ MONITOR_PATCH_TYPE_ERROR_CHECKSUM,
-+ MONITOR_PATCH_TYPE_HDTV_WITH_PURE_DFP_EDID,
-+ MONITOR_PATCH_TYPE_DO_NOT_USE_DETAILED_TIMING,
-+ MONITOR_PATCH_TYPE_DO_NOT_USE_RANGE_LIMITATION,
-+ MONITOR_PATCH_TYPE_EDID_EXTENTION_ERROR_CHECK_SUM,
-+ MONITOR_PATCH_TYPE_TURN_OFF_DISPLAY_BEFORE_MODE_CHANGE,
-+ MONITOR_PATCH_TYPE_RESTRICT_VESA_MODE_TIMING,
-+ MONITOR_PATCH_TYPE_DO_NOT_USE_EDID_MAX_PIX_CLK,
-+ MONITOR_PATCH_TYPE_VENDOR_0,
-+ MONITOR_PATCH_TYPE_RANDOM_CRT,
-+ MONITOR_PATCH_TYPE_VENDOR_1,
-+ MONITOR_PATCH_TYPE_LIMIT_PANEL_SUPPORT_RGB_ONLY,
-+ MONITOR_PATCH_TYPE_PACKED_PIXEL_FORMAT,
-+ MONITOR_PATCH_TYPE_LARGE_PANEL,
-+ MONITOR_PATCH_TYPE_STEREO_SUPPORT,
-+ /* 0 (default) - mean patch will not be applied, however it can be
-+ * explicitly set to 1
-+ */
-+ MONITOR_PATCH_TYPE_DUAL_EDID_PANEL,
-+ MONITOR_PATCH_TYPE_IGNORE_19X12_STD_TIMING,
-+ MONITOR_PATCH_TYPE_MULTIPLE_PACKED_TYPE,
-+ MONITOR_PATCH_TYPE_RESET_TX_ON_DISPLAY_POWER_ON,
-+ MONITOR_PATCH_TYPE_VENDOR_2,
-+ MONITOR_PATCH_TYPE_RESTRICT_PROT_DUAL_LINK_DVI,
-+ MONITOR_PATCH_TYPE_FORCE_LINK_RATE,
-+ MONITOR_PATCH_TYPE_DELAY_AFTER_DP_RECEIVER_POWER_UP,
-+ MONITOR_PATCH_TYPE_KEEP_DP_RECEIVER_POWERED,
-+ MONITOR_PATCH_TYPE_DELAY_BEFORE_READ_EDID,
-+ MONITOR_PATCH_TYPE_DELAY_AFTER_PIXEL_FORMAT_CHANGE,
-+ MONITOR_PATCH_TYPE_INCREASE_DEFER_WRITE_RETRY_I2C_OVER_AUX,
-+ MONITOR_PATCH_TYPE_NO_DEFAULT_TIMINGS,
-+ MONITOR_PATCH_TYPE_ADD_CEA861_DETAILED_TIMING_VIC16,
-+ MONITOR_PATCH_TYPE_ADD_CEA861_DETAILED_TIMING_VIC31,
-+ MONITOR_PATCH_TYPE_DELAY_BEFORE_UNMUTE,
-+ MONITOR_PATCH_TYPE_RETRY_LINK_TRAINING_ON_FAILURE,
-+ MONITOR_PATCH_TYPE_ALLOW_AUX_WHEN_HPD_LOW,
-+ MONITOR_PATCH_TYPE_TILED_DISPLAY,
-+ MONITOR_PATCH_TYPE_DISABLE_PSR_ENTRY_ABORT,
-+ MONITOR_PATCH_TYPE_EDID_EXTENTION_ERROR_CHECKSUM,
-+ MONITOR_PATCH_TYPE_ALLOW_ONLY_CE_MODE,
-+ MONITOR_PATCH_TYPE_VID_STREAM_DIFFER_TO_SYNC,
-+ MONITOR_PATCH_TYPE_EXTRA_DELAY_ON_DISCONNECT,
-+ MONITOR_PATCH_TYPE_DELAY_AFTER_DISABLE_BACKLIGHT_DFS_BYPASS,
-+ MONITOR_PATCH_TYPE_SINGLE_MODE_PACKED_PIXEL
-+};
-+
-+/* Single entry in the monitor table */
-+struct monitor_patch_info {
-+ enum monitor_manufacturer_id manufacturer_id;
-+ enum monitor_product_id product_id;
-+ enum monitor_patch_type type;
-+ uint32_t param;
-+};
-+
-+union dcs_monitor_patch_flags {
-+ struct {
-+ bool ERROR_CHECKSUM:1;
-+ bool HDTV_WITH_PURE_DFP_EDID:1;
-+ bool DO_NOT_USE_DETAILED_TIMING:1;
-+ bool DO_NOT_USE_RANGE_LIMITATION:1;
-+ bool EDID_EXTENTION_ERROR_CHECKSUM:1;
-+ bool TURN_OFF_DISPLAY_BEFORE_MODE_CHANGE:1;
-+ bool RESTRICT_VESA_MODE_TIMING:1;
-+ bool DO_NOT_USE_EDID_MAX_PIX_CLK:1;
-+ bool VENDOR_0:1;
-+ bool RANDOM_CRT:1;/* 10 bits used including this one-*/
-+ bool VENDOR_1:1;
-+ bool LIMIT_PANEL_SUPPORT_RGB_ONLY:1;
-+ bool PACKED_PIXEL_FORMAT:1;
-+ bool LARGE_PANEL:1;
-+ bool STEREO_SUPPORT:1;
-+ bool DUAL_EDID_PANEL:1;
-+ bool IGNORE_19X12_STD_TIMING:1;
-+ bool MULTIPLE_PACKED_TYPE:1;
-+ bool RESET_TX_ON_DISPLAY_POWER_ON:1;
-+ bool ALLOW_ONLY_CE_MODE:1;/* 20 bits used including this one*/
-+ bool RESTRICT_PROT_DUAL_LINK_DVI:1;
-+ bool FORCE_LINK_RATE:1;
-+ bool DELAY_AFTER_DP_RECEIVER_POWER_UP:1;
-+ bool KEEP_DP_RECEIVER_POWERED:1;
-+ bool DELAY_BEFORE_READ_EDID:1;
-+ bool DELAY_AFTER_PIXEL_FORMAT_CHANGE:1;
-+ bool INCREASE_DEFER_WRITE_RETRY_I2C_OVER_AUX:1;
-+ bool NO_DEFAULT_TIMINGS:1;
-+ bool ADD_CEA861_DETAILED_TIMING_VIC16:1;
-+ bool ADD_CEA861_DETAILED_TIMING_VIC31:1; /* 30 bits*/
-+ bool DELAY_BEFORE_UNMUTE:1;
-+ bool RETRY_LINK_TRAINING_ON_FAILURE:1;
-+ bool ALLOW_AUX_WHEN_HPD_LOW:1;
-+ bool TILED_DISPLAY:1;
-+ bool DISABLE_PSR_ENTRY_ABORT:1;
-+ bool INTERMITTENT_EDID_ERROR:1;/* 36 bits total*/
-+ bool VID_STREAM_DIFFER_TO_SYNC:1;/* 37 bits total*/
-+ bool EXTRA_DELAY_ON_DISCONNECT:1;/* 38 bits total*/
-+ bool DELAY_AFTER_DISABLE_BACKLIGHT_DFS_BYPASS:1;/* 39 bits total*/
-+ } flags;
-+ uint64_t raw;
-+};
-+
-+struct dcs_edid_supported_max_bw {
-+ uint32_t pix_clock_khz;
-+ uint32_t bits_per_pixel;
-+};
-+
-+struct dcs_stereo_3d_features {
-+ struct {
-+/* 3D Format supported by monitor (implies supported by driver)*/
-+ uint32_t SUPPORTED:1;
-+/* 3D Format supported on all timings
-+(no need to check every timing for 3D support)*/
-+ uint32_t ALL_TIMINGS:1;
-+/* 3D Format supported in clone mode*/
-+ uint32_t CLONE_MODE:1;
-+/* Scaling allowed when driving 3D Format*/
-+ uint32_t SCALING:1;
-+/* Left and right images packed by SW within single frame*/
-+ uint32_t SINGLE_FRAME_SW_PACKED:1;
-+ } flags;
-+};
-+
-+struct dcs_container_id {
-+ /*128bit GUID in binary form*/
-+ uint8_t guid[16];
-+ /* 8 byte port ID -> ELD.PortID*/
-+ uint32_t port_id[2];
-+ /* 2 byte manufacturer name -> ELD.ManufacturerName*/
-+ uint16_t manufacturer_name;
-+ /* 2 byte product code -> ELD.ProductCode*/
-+ uint16_t product_code;
-+};
-+
-+struct dcs_display_tile {
-+/*unique Id of Tiled Display. 0 - means display is not part in Tiled Display*/
-+ uint64_t id;
-+ uint32_t rows;/* size of Tiled Display in tiles*/
-+ uint32_t cols;/* size of Tiled Display in tiles*/
-+ uint32_t width;/* size of current Tile in pixels*/
-+ uint32_t height;/* size of current Tile in pixels*/
-+ uint32_t row;/* location of current Tile*/
-+ uint32_t col;/* location of current Tile*/
-+ struct {
-+ /*in pixels*/
-+ uint32_t left;
-+ uint32_t right;
-+ uint32_t top;
-+ uint32_t bottom;
-+ } bezel;/* bezel information of current tile*/
-+
-+ struct {
-+ uint32_t SEPARATE_ENCLOSURE:1;
-+ uint32_t BEZEL_INFO_PRESENT:1;
-+ uint32_t CAN_SCALE:1;
-+ } flags;
-+
-+ struct {
-+ uint32_t manufacturer_id;
-+ uint32_t product_id;
-+ uint32_t serial_id;
-+ } topology_id;
-+};
-+
-+#endif /* __DAL_DCS_TYPES_H__ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/include/ddc_interface.h b/drivers/gpu/drm/amd/dal/include/ddc_interface.h
-new file mode 100644
-index 0000000..22fd31f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/ddc_interface.h
-@@ -0,0 +1,74 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DDC_INTERFACE_H__
-+#define __DAL_DDC_INTERFACE_H__
-+
-+#include "gpio_types.h"
-+
-+struct ddc;
-+
-+enum gpio_result dal_ddc_open(
-+ struct ddc *ddc,
-+ enum gpio_mode mode,
-+ enum gpio_ddc_config_type config_type);
-+
-+enum gpio_result dal_ddc_get_clock(
-+ const struct ddc *ddc,
-+ uint32_t *value);
-+
-+enum gpio_result dal_ddc_set_clock(
-+ const struct ddc *ddc,
-+ uint32_t value);
-+
-+enum gpio_result dal_ddc_get_data(
-+ const struct ddc *ddc,
-+ uint32_t *value);
-+
-+enum gpio_result dal_ddc_set_data(
-+ const struct ddc *ddc,
-+ uint32_t value);
-+
-+enum gpio_result dal_ddc_change_mode(
-+ struct ddc *ddc,
-+ enum gpio_mode mode);
-+
-+bool dal_ddc_is_hw_supported(
-+ const struct ddc *ddc);
-+
-+enum gpio_ddc_line dal_ddc_get_line(
-+ const struct ddc *ddc);
-+
-+bool dal_ddc_check_line_aborted(
-+ const struct ddc *ddc);
-+
-+enum gpio_result dal_ddc_set_config(
-+ struct ddc *ddc,
-+ enum gpio_ddc_config_type config_type);
-+
-+void dal_ddc_close(
-+ struct ddc *ddc);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/ddc_service_interface.h b/drivers/gpu/drm/amd/dal/include/ddc_service_interface.h
-new file mode 100644
-index 0000000..ca3e6ce
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/ddc_service_interface.h
-@@ -0,0 +1,100 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef __DAL_DDC_SERVICE_INTERFACE_H__
-+#define __DAL_DDC_SERVICE_INTERFACE_H__
-+
-+#include "ddc_service_types.h"
-+
-+struct ddc_service;
-+struct adapter_service;
-+struct graphics_object_id;
-+enum ddc_result;
-+struct av_sync_data;
-+struct dp_receiver_id_info;
-+
-+struct ddc_service_init_data {
-+ struct adapter_service *as;
-+ struct graphics_object_id id;
-+ struct dc_context *ctx;
-+};
-+struct ddc_service *dal_ddc_service_create(
-+ struct ddc_service_init_data *ddc_init_data);
-+
-+void dal_ddc_service_destroy(struct ddc_service **ddc);
-+
-+enum ddc_service_type dal_ddc_service_get_type(struct ddc_service *ddc);
-+
-+void dal_ddc_service_set_transaction_type(
-+ struct ddc_service *ddc,
-+ enum ddc_transaction_type type);
-+
-+bool dal_ddc_service_is_in_aux_transaction_mode(struct ddc_service *ddc);
-+
-+uint32_t dal_ddc_service_edid_query(struct ddc_service *ddc);
-+
-+uint32_t dal_ddc_service_get_edid_buf_len(struct ddc_service *ddc);
-+
-+void dal_ddc_service_get_edid_buf(struct ddc_service *ddc, uint8_t *edid_buf);
-+
-+void dal_ddc_service_i2c_query_dp_dual_mode_adaptor(
-+ struct ddc_service *ddc,
-+ struct display_sink_capability *sink_cap);
-+
-+bool dal_ddc_service_query_ddc_data(
-+ struct ddc_service *ddc,
-+ uint32_t address,
-+ uint8_t *write_buf,
-+ uint32_t write_size,
-+ uint8_t *read_buf,
-+ uint32_t read_size);
-+
-+bool dal_ddc_service_get_dp_receiver_id_info(
-+ struct ddc_service *ddc,
-+ struct dp_receiver_id_info *info);
-+
-+enum ddc_result dal_ddc_service_read_dpcd_data(
-+ struct ddc_service *ddc,
-+ uint32_t address,
-+ uint8_t *data,
-+ uint32_t len);
-+
-+enum ddc_result dal_ddc_service_write_dpcd_data(
-+ struct ddc_service *ddc,
-+ uint32_t address,
-+ const uint8_t *data,
-+ uint32_t len);
-+
-+void dal_ddc_service_write_scdc_data(
-+ struct ddc_service *ddc_service,
-+ uint32_t pix_clk,
-+ bool lte_340_scramble);
-+
-+void dal_ddc_service_read_scdc_data(
-+ struct ddc_service *ddc_service);
-+
-+void ddc_service_set_dongle_type(struct ddc_service *ddc,
-+ enum display_dongle_type dongle_type);
-+
-+#endif /* __DAL_DDC_SERVICE_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/ddc_service_types.h b/drivers/gpu/drm/amd/dal/include/ddc_service_types.h
-new file mode 100644
-index 0000000..47ad2ed
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/ddc_service_types.h
-@@ -0,0 +1,220 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+#ifndef __DAL_DDC_SERVICE_TYPES_H__
-+#define __DAL_DDC_SERVICE_TYPES_H__
-+
-+#include "include/hw_sequencer_types.h"
-+
-+#define DP_BRANCH_DEVICE_ID_1 0x0010FA
-+#define DP_BRANCH_DEVICE_ID_2 0x0022B9
-+#define DP_SINK_DEVICE_ID_1 0x4CE000
-+#define DP_BRANCH_DEVICE_ID_3 0x00001A
-+#define DP_BRANCH_DEVICE_ID_4 0x0080e1
-+#define DP_BRANCH_DEVICE_ID_5 0x006037
-+#define DP_SINK_DEVICE_ID_2 0x001CF8
-+
-+
-+enum ddc_result {
-+ DDC_RESULT_UNKNOWN = 0,
-+ DDC_RESULT_SUCESSFULL,
-+ DDC_RESULT_FAILED_CHANNEL_BUSY,
-+ DDC_RESULT_FAILED_TIMEOUT,
-+ DDC_RESULT_FAILED_PROTOCOL_ERROR,
-+ DDC_RESULT_FAILED_NACK,
-+ DDC_RESULT_FAILED_INCOMPLETE,
-+ DDC_RESULT_FAILED_OPERATION,
-+ DDC_RESULT_FAILED_INVALID_OPERATION,
-+ DDC_RESULT_FAILED_BUFFER_OVERFLOW
-+};
-+
-+enum ddc_service_type {
-+ DDC_SERVICE_TYPE_CONNECTOR,
-+ DDC_SERVICE_TYPE_DISPLAY_PORT_MST,
-+};
-+
-+enum ddc_transaction_type {
-+ DDC_TRANSACTION_TYPE_NONE = 0,
-+ DDC_TRANSACTION_TYPE_I2C,
-+ DDC_TRANSACTION_TYPE_I2C_OVER_AUX,
-+ DDC_TRANSACTION_TYPE_I2C_OVER_AUX_WITH_DEFER,
-+ DDC_TRANSACTION_TYPE_I2C_OVER_AUX_RETRY_DEFER
-+};
-+
-+enum display_dongle_type {
-+ DISPLAY_DONGLE_NONE = 0,
-+ /* Active converter types*/
-+ DISPLAY_DONGLE_DP_VGA_CONVERTER,
-+ DISPLAY_DONGLE_DP_DVI_CONVERTER,
-+ DISPLAY_DONGLE_DP_HDMI_CONVERTER,
-+ /* DP-HDMI/DVI passive dongles (Type 1 and Type 2)*/
-+ DISPLAY_DONGLE_DP_DVI_DONGLE,
-+ DISPLAY_DONGLE_DP_HDMI_DONGLE,
-+ /* Other types of dongle*/
-+ DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE,
-+};
-+
-+enum dcs_dpcd_revision {
-+ DCS_DPCD_REV_10 = 0x10,
-+ DCS_DPCD_REV_11 = 0x11,
-+ DCS_DPCD_REV_12 = 0x12
-+};
-+
-+/**
-+ * display sink capability
-+ */
-+struct display_sink_capability {
-+ /* dongle type (DP converter, CV smart dongle) */
-+ enum display_dongle_type dongle_type;
-+
-+ /**********************************************************
-+ capabilities going INTO SINK DEVICE (stream capabilities)
-+ **********************************************************/
-+ /* Dongle's downstream count. */
-+ uint32_t downstrm_sink_count;
-+ /* Is dongle's downstream count info field (downstrm_sink_count)
-+ * valid. */
-+ bool downstrm_sink_count_valid;
-+
-+ /* Maximum additional audio delay in microsecond (us) */
-+ uint32_t additional_audio_delay;
-+ /* Audio latency value in microsecond (us) */
-+ uint32_t audio_latency;
-+ /* Interlace video latency value in microsecond (us) */
-+ uint32_t video_latency_interlace;
-+ /* Progressive video latency value in microsecond (us) */
-+ uint32_t video_latency_progressive;
-+ /* Dongle caps: Maximum pixel clock supported over dongle for HDMI */
-+ uint32_t max_hdmi_pixel_clock;
-+ /* Dongle caps: Maximum deep color supported over dongle for HDMI */
-+ enum dc_color_depth max_hdmi_deep_color;
-+
-+ /************************************************************
-+ capabilities going OUT OF SOURCE DEVICE (link capabilities)
-+ ************************************************************/
-+ /* support for Spread Spectrum(SS) */
-+ bool ss_supported;
-+ /* DP link settings (laneCount, linkRate, Spread) */
-+ uint32_t dp_link_lane_count;
-+ uint32_t dp_link_rate;
-+ uint32_t dp_link_spead;
-+
-+ enum dcs_dpcd_revision dpcd_revision;
-+ /* If dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER,
-+ indicates 'Frame Sequential-to-lllFrame Pack' conversion capability.*/
-+ bool is_dp_hdmi_s3d_converter;
-+ /* to check if we have queried the display capability
-+ * for eDP panel already. */
-+ bool is_edp_sink_cap_valid;
-+};
-+
-+struct dp_receiver_id_info {
-+ uint32_t dpcd_rev;
-+ uint32_t sink_id;
-+ int8_t sink_id_str[6];
-+ int8_t sink_hw_revision;
-+ int8_t sink_fw_revision[2];
-+ uint32_t branch_id;
-+ int8_t branch_name[6];
-+ enum display_dongle_type dongle_type;
-+};
-+
-+struct av_sync_data {
-+ uint8_t av_granularity;/* DPCD 00023h */
-+ uint8_t aud_dec_lat1;/* DPCD 00024h */
-+ uint8_t aud_dec_lat2;/* DPCD 00025h */
-+ uint8_t aud_pp_lat1;/* DPCD 00026h */
-+ uint8_t aud_pp_lat2;/* DPCD 00027h */
-+ uint8_t vid_inter_lat;/* DPCD 00028h */
-+ uint8_t vid_prog_lat;/* DPCD 00029h */
-+ uint8_t aud_del_ins1;/* DPCD 0002Bh */
-+ uint8_t aud_del_ins2;/* DPCD 0002Ch */
-+ uint8_t aud_del_ins3;/* DPCD 0002Dh */
-+};
-+
-+/** EDID retrieval related constants, also used by MstMgr **/
-+
-+#define DDC_EDID_SEGMENT_SIZE 256
-+#define DDC_EDID_BLOCK_SIZE 128
-+#define DDC_EDID_BLOCKS_PER_SEGMENT \
-+ (DDC_EDID_SEGMENT_SIZE / DDC_EDID_BLOCK_SIZE)
-+
-+#define DDC_EDID_EXT_COUNT_OFFSET 0x7E
-+
-+#define DDC_EDID_ADDRESS_START 0x50
-+#define DDC_EDID_ADDRESS_END 0x52
-+#define DDC_EDID_SEGMENT_ADDRESS 0x30
-+
-+/* signatures for Edid 1x */
-+#define DDC_EDID1X_VENDORID_SIGNATURE_OFFSET 8
-+#define DDC_EDID1X_VENDORID_SIGNATURE_LEN 4
-+#define DDC_EDID1X_EXT_CNT_AND_CHECKSUM_OFFSET 126
-+#define DDC_EDID1X_EXT_CNT_AND_CHECKSUM_LEN 2
-+#define DDC_EDID1X_CHECKSUM_OFFSET 127
-+/* signatures for Edid 20*/
-+#define DDC_EDID_20_SIGNATURE_OFFSET 0
-+#define DDC_EDID_20_SIGNATURE 0x20
-+
-+#define DDC_EDID20_VENDORID_SIGNATURE_OFFSET 1
-+#define DDC_EDID20_VENDORID_SIGNATURE_LEN 4
-+#define DDC_EDID20_CHECKSUM_OFFSET 255
-+#define DDC_EDID20_CHECKSUM_LEN 1
-+
-+/*DP to VGA converter*/
-+static const uint8_t DP_VGA_CONVERTER_ID_1[] = "mVGAa";
-+/*DP to Dual link DVI converter*/
-+static const uint8_t DP_DVI_CONVERTER_ID_1[] = "m2DVIa";
-+/*Travis*/
-+static const uint8_t DP_VGA_LVDS_CONVERTER_ID_2[] = "sivarT";
-+/*Nutmeg*/
-+static const uint8_t DP_VGA_LVDS_CONVERTER_ID_3[] = "dnomlA";
-+/*DP to VGA converter*/
-+static const uint8_t DP_VGA_CONVERTER_ID_4[] = "DpVga";
-+/*DP to Dual link DVI converter*/
-+static const uint8_t DP_DVI_CONVERTER_ID_4[] = "m2DVIa";
-+/*DP to Dual link DVI converter 2*/
-+static const uint8_t DP_DVI_CONVERTER_ID_42[] = "v2DVIa";
-+
-+static const uint8_t DP_SINK_DEV_STRING_ID2_REV0[] = "\0\0\0\0\0\0";
-+
-+/* Identifies second generation PSR TCON from Parade: Device ID string:
-+ * yy-xx-**-**-**-**
-+ */
-+/* xx - Hw ID high byte */
-+static const uint32_t DP_SINK_DEV_STRING_ID2_REV1_HW_ID_HIGH_BYTE =
-+ 0x06;
-+
-+/* yy - HW ID low byte, the same silicon has several package/feature flavors */
-+static const uint32_t DP_SINK_DEV_STRING_ID2_REV1_HW_ID_LOW_BYTE1 =
-+ 0x61;
-+static const uint32_t DP_SINK_DEV_STRING_ID2_REV1_HW_ID_LOW_BYTE2 =
-+ 0x62;
-+static const uint32_t DP_SINK_DEV_STRING_ID2_REV1_HW_ID_LOW_BYTE3 =
-+ 0x63;
-+static const uint32_t DP_SINK_DEV_STRING_ID2_REV1_HW_ID_LOW_BYTE4 =
-+ 0x72;
-+static const uint32_t DP_SINK_DEV_STRING_ID2_REV1_HW_ID_LOW_BYTE5 =
-+ 0x73;
-+
-+#endif /* __DAL_DDC_SERVICE_TYPES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/default_mode_list_interface.h b/drivers/gpu/drm/amd/dal/include/default_mode_list_interface.h
-new file mode 100644
-index 0000000..35a5695
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/default_mode_list_interface.h
-@@ -0,0 +1,37 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DEFAULT_MODE_LIST_INTERFACE_H__
-+#define __DAL_DEFAULT_MODE_LIST_INTERFACE_H__
-+
-+struct default_mode_list;
-+
-+uint32_t dal_default_mode_list_get_count(const struct default_mode_list *dml);
-+
-+struct dc_mode_info *dal_default_mode_list_get_mode_info_at_index(
-+ const struct default_mode_list *dml,
-+ uint32_t index);
-+
-+#endif /*__DAL_DEFAULT_MODE_LIST_INTERFACE_H__*/
-diff --git a/drivers/gpu/drm/amd/dal/include/display_clock_interface.h b/drivers/gpu/drm/amd/dal/include/display_clock_interface.h
-new file mode 100644
-index 0000000..2f48b8a
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/display_clock_interface.h
-@@ -0,0 +1,189 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DISPLAY_CLOCK_INTERFACE_H__
-+#define __DISPLAY_CLOCK_INTERFACE_H__
-+
-+#include "hw_sequencer_types.h"
-+#include "grph_object_defs.h"
-+#include "signal_types.h"
-+#include "scaler_types.h"
-+
-+/* Timing related information*/
-+struct dc_timing_params {
-+ uint32_t INTERLACED:1;
-+ uint32_t HCOUNT_BY_TWO:1;
-+ uint32_t PIXEL_REPETITION:4; /*< values 1 to 10 supported*/
-+ uint32_t PREFETCH:1;
-+
-+ uint32_t h_total;
-+ uint32_t h_addressable;
-+ uint32_t h_sync_width;
-+};
-+
-+/* Scaling related information*/
-+struct dc_scaling_params {
-+ uint32_t h_overscan_right;
-+ uint32_t h_overscan_left;
-+ uint32_t h_taps;
-+ uint32_t v_taps;
-+};
-+
-+/*Display Request Mode (1 and 2 valid when scaler is OFF)*/
-+enum display_request_mode {
-+ REQUEST_ONLY_AT_EVERY_READ_POINTER_INCREMENT = 0,
-+ REQUEST_WAITING_FOR_THE_FIRST_READ_POINTER_ONLY,
-+ REQUEST_WITHOUT_WAITING_FOR_READ_POINTER
-+};
-+
-+/* FBC minimum CompressionRatio*/
-+enum fbc_compression_ratio {
-+ FBC_COMPRESSION_NOT_USED = 0,
-+ FBC_MINIMUM_COMPRESSION_RATIO_1 = 1,
-+ FBC_MINIMUM_COMPRESSION_RATIO_2 = 2,
-+ FBC_MINIMUM_COMPRESSION_RATIO_4 = 4,
-+ FBC_MINIMUM_COMPRESSION_RATIO_8 = 8
-+};
-+
-+/* VScalerEfficiency */
-+enum v_scaler_efficiency {
-+ V_SCALER_EFFICIENCY_LB36BPP = 0,
-+ V_SCALER_EFFICIENCY_LB30BPP = 1,
-+ V_SCALER_EFFICIENCY_LB24BPP = 2,
-+ V_SCALER_EFFICIENCY_LB18BPP = 3
-+};
-+
-+/* Parameters required for minimum Engine
-+ * and minimum Display clock calculations*/
-+struct min_clock_params {
-+ uint32_t id;
-+ uint32_t requested_pixel_clock; /* in KHz */
-+ uint32_t actual_pixel_clock; /* in KHz */
-+ struct view source_view;
-+ struct view dest_view;
-+ struct dc_timing_params timing_info;
-+ struct dc_scaling_params scaling_info;
-+ struct color_quality color_info;
-+ enum signal_type signal_type;
-+ enum dc_color_depth deep_color_depth;
-+ enum v_scaler_efficiency scaler_efficiency;
-+ bool line_buffer_prefetch_enabled;
-+};
-+
-+/* Enumerations for Source selection of the Display clock */
-+enum display_clock_source_select {
-+ USE_PIXEL_CLOCK_PLL = 0,
-+ USE_EXTERNAL_CLOCK,
-+ USE_ENGINE_CLOCK
-+};
-+
-+/* Result of Minimum System and Display clock calculations.
-+ * Minimum System clock and Display clock, source and path to be used
-+ * for Display clock*/
-+struct minimum_clocks_calculation_result {
-+ uint32_t min_sclk_khz;
-+ uint32_t min_dclk_khz;
-+ uint32_t min_mclk_khz;
-+ uint32_t min_deep_sleep_sclk;
-+};
-+
-+/* Enumeration of all clocks states */
-+enum clocks_state {
-+ CLOCKS_STATE_INVALID,
-+ CLOCKS_STATE_ULTRA_LOW,
-+ CLOCKS_STATE_LOW,
-+ CLOCKS_STATE_NOMINAL,
-+ CLOCKS_STATE_PERFORMANCE
-+};
-+
-+/* Structure containing all state-dependent clocks
-+ * (dependent on "enum clocks_state") */
-+struct state_dependent_clocks {
-+ uint32_t display_clk_khz;
-+ uint32_t pixel_clk_khz;
-+ uint32_t dvo_clk_khz;
-+};
-+
-+struct display_clock_state {
-+ uint32_t DFS_BYPASS_ACTIVE:1;
-+};
-+
-+struct display_clock;
-+
-+struct display_clock *dal_display_clock_dce110_create(
-+ struct dc_context *ctx,
-+ struct adapter_service *as);
-+
-+struct display_clock *dal_display_clock_dce80_create(
-+ struct dc_context *ctx,
-+ struct adapter_service *as);
-+
-+void dal_display_clock_destroy(struct display_clock **to_destroy);
-+bool dal_display_clock_validate(
-+ struct display_clock *disp_clk,
-+ struct min_clock_params *params);
-+uint32_t dal_display_clock_calculate_min_clock(
-+ struct display_clock *disp_clk,
-+ uint32_t path_num,
-+ struct min_clock_params *params);
-+uint32_t dal_display_clock_get_validation_clock(struct display_clock *disp_clk);
-+void dal_display_clock_set_clock(
-+ struct display_clock *disp_clk,
-+ uint32_t requested_clock_khz);
-+uint32_t dal_display_clock_get_clock(struct display_clock *disp_clk);
-+enum clocks_state dal_display_clock_get_min_clocks_state(
-+ struct display_clock *disp_clk);
-+enum clocks_state dal_display_clock_get_required_clocks_state(
-+ struct display_clock *disp_clk,
-+ struct state_dependent_clocks *req_clocks);
-+bool dal_display_clock_set_min_clocks_state(
-+ struct display_clock *disp_clk,
-+ enum clocks_state clocks_state);
-+uint32_t dal_display_clock_get_dp_ref_clk_frequency(
-+ struct display_clock *disp_clk);
-+/*the second parameter of "switchreferenceclock" is
-+ * a dummy argument for all pre dce 6.0 versions*/
-+void dal_display_clock_switch_reference_clock(
-+ struct display_clock *disp_clk,
-+ bool use_external_ref_clk,
-+ uint32_t requested_clock_khz);
-+void dal_display_clock_set_dp_ref_clock_source(
-+ struct display_clock *disp_clk,
-+ enum clock_source_id clk_src);
-+void dal_display_clock_store_max_clocks_state(
-+ struct display_clock *disp_clk,
-+ enum clocks_state max_clocks_state);
-+void dal_display_clock_set_clock_state(
-+ struct display_clock *disp_clk,
-+ struct display_clock_state clk_state);
-+struct display_clock_state dal_display_clock_get_clock_state(
-+ struct display_clock *disp_clk);
-+uint32_t dal_display_clock_get_dfs_bypass_threshold(
-+ struct display_clock *disp_clk);
-+void dal_display_clock_invalid_clock_state(
-+ struct display_clock *disp_clk);
-+
-+
-+#endif /* __DISPLAY_CLOCK_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/display_path_interface.h b/drivers/gpu/drm/amd/dal/include/display_path_interface.h
-new file mode 100644
-index 0000000..7bf2ef2
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/display_path_interface.h
-@@ -0,0 +1,436 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DISPLAY_PATH_INTERFACE_H__
-+#define __DISPLAY_PATH_INTERFACE_H__
-+
-+#include "display_path_types.h"
-+#include "dcs_types.h"
-+#include "grph_object_ctrl_defs.h"
-+#include "signal_types.h"
-+#include "controller_types.h"
-+
-+struct encoder;
-+struct controller;
-+struct connector;
-+struct audio;
-+struct clock_source;
-+struct link_service;
-+struct goc_link_service_data;
-+struct drr_config;
-+
-+struct display_path;
-+
-+struct display_path *dal_display_path_create(void);
-+
-+struct display_path *dal_display_path_clone(
-+ const struct display_path *self,
-+ bool copy_active_state);
-+
-+void dal_display_path_destroy(
-+ struct display_path **to_destroy);
-+
-+bool dal_display_path_validate(
-+ struct display_path *path,
-+ enum signal_type sink_signal);
-+
-+bool dal_display_path_add_link(
-+ struct display_path *path,
-+ struct encoder *encoder);
-+
-+bool dal_display_path_add_connector(
-+ struct display_path *path,
-+ struct connector *connector);
-+
-+struct connector *dal_display_path_get_connector(
-+ struct display_path *path);
-+
-+int32_t dal_display_path_acquire(
-+ struct display_path *path);
-+
-+bool dal_display_path_is_acquired(
-+ const struct display_path *path);
-+
-+int32_t dal_display_path_get_ref_counter(
-+ const struct display_path *path);
-+
-+int32_t dal_display_path_release(
-+ struct display_path *path);
-+
-+void dal_display_path_release_resources(
-+ struct display_path *path);
-+
-+void dal_display_path_acquire_links(
-+ struct display_path *path);
-+
-+bool dal_display_path_is_source_blanked(
-+ const struct display_path *path);
-+
-+bool dal_display_path_is_source_unblanked(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_source_blanked(
-+ struct display_path *path,
-+ enum display_tri_state state);
-+
-+bool dal_display_path_is_target_blanked(
-+ const struct display_path *path);
-+
-+bool dal_display_path_is_target_unblanked(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_target_blanked(
-+ struct display_path *path,
-+ enum display_tri_state state);
-+
-+bool dal_display_path_is_target_powered_on(
-+ const struct display_path *path);
-+
-+bool dal_display_path_is_target_powered_off(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_target_powered_on(
-+ struct display_path *path,
-+ enum display_tri_state state);
-+
-+bool dal_display_path_is_target_connected(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_target_connected(
-+ struct display_path *path,
-+ bool c);
-+
-+uint32_t dal_display_path_get_display_index(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_display_index(
-+ struct display_path *path,
-+ uint32_t index);
-+
-+struct connector_device_tag_info *dal_display_path_get_device_tag(
-+ struct display_path *path);
-+
-+void dal_display_path_set_device_tag(
-+ struct display_path *path,
-+ struct connector_device_tag_info tag);
-+
-+enum clock_sharing_group dal_display_path_get_clock_sharing_group(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_clock_sharing_group(
-+ struct display_path *path,
-+ enum clock_sharing_group clock);
-+
-+union display_path_properties dal_display_path_get_properties(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_properties(
-+ struct display_path *path,
-+ union display_path_properties p);
-+
-+struct dcs *dal_display_path_get_dcs(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_dcs(
-+ struct display_path *path,
-+ struct dcs *dcs);
-+
-+uint32_t dal_display_path_get_number_of_links(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_controller(
-+ struct display_path *path,
-+ struct controller *controller);
-+
-+struct controller *dal_display_path_get_controller(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_clock_source(
-+ struct display_path *path,
-+ struct clock_source *clock);
-+
-+struct clock_source *dal_display_path_get_clock_source(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_alt_clock_source(
-+ struct display_path *path,
-+ struct clock_source *clock);
-+
-+struct clock_source *dal_display_path_get_alt_clock_source(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_fbc_info(
-+ struct display_path *path,
-+ struct fbc_info *clock);
-+
-+struct fbc_info *dal_display_path_get_fbc_info(
-+ struct display_path *path);
-+
-+void dal_display_path_set_drr_config(
-+ struct display_path *path,
-+ struct drr_config *clock);
-+
-+void dal_display_path_get_drr_config(
-+ const struct display_path *path,
-+ struct drr_config *clock);
-+
-+void dal_display_path_set_static_screen_triggers(
-+ struct display_path *path,
-+ const struct static_screen_events *events);
-+
-+void dal_display_path_get_static_screen_triggers(
-+ const struct display_path *path,
-+ struct static_screen_events *events);
-+
-+bool dal_display_path_is_psr_supported(
-+ const struct display_path *path);
-+
-+bool dal_display_path_is_drr_supported(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_link_service_data(
-+ struct display_path *path,
-+ uint32_t idx,
-+ const struct goc_link_service_data *data);
-+
-+bool dal_display_path_get_link_service_data(
-+ const struct display_path *path,
-+ uint32_t idx,
-+ struct goc_link_service_data *data);
-+
-+struct link_service *dal_display_path_get_link_query_interface(
-+ const struct display_path *path,
-+ uint32_t idx);
-+
-+void dal_display_path_set_link_query_interface(
-+ struct display_path *path,
-+ uint32_t idx,
-+ struct link_service *link);
-+
-+struct link_service *dal_display_path_get_link_config_interface(
-+ const struct display_path *path,
-+ uint32_t idx);
-+
-+struct link_service *dal_display_path_get_link_service_interface(
-+ const struct display_path *path,
-+ uint32_t idx);
-+
-+struct encoder *dal_display_path_get_upstream_encoder(
-+ const struct display_path *path,
-+ uint32_t idx);
-+
-+struct encoder *dal_display_path_get_upstream_object(
-+ const struct display_path *path,
-+ uint32_t idx);
-+
-+struct encoder *dal_display_path_get_downstream_encoder(
-+ const struct display_path *path,
-+ uint32_t idx);
-+
-+struct encoder *dal_display_path_get_downstream_object(
-+ const struct display_path *path,
-+ uint32_t idx);
-+
-+struct audio *dal_display_path_get_audio(
-+ const struct display_path *path,
-+ uint32_t idx);
-+
-+void dal_display_path_set_audio(
-+ struct display_path *path,
-+ uint32_t idx,
-+ struct audio *a);
-+
-+struct audio *dal_display_path_get_audio_object(
-+ const struct display_path *path,
-+ uint32_t idx);
-+
-+void dal_display_path_set_audio_active_state(
-+ struct display_path *path,
-+ uint32_t idx,
-+ bool state);
-+
-+enum engine_id dal_display_path_get_stream_engine(
-+ const struct display_path *path,
-+ uint32_t idx);
-+
-+void dal_display_path_set_stream_engine(
-+ struct display_path *path,
-+ uint32_t idx,
-+ enum engine_id id);
-+
-+bool dal_display_path_is_link_active(
-+ const struct display_path *path,
-+ uint32_t idx);
-+
-+void dal_display_path_set_link_active_state(
-+ struct display_path *path,
-+ uint32_t idx,
-+ bool state);
-+
-+enum signal_type dal_display_path_get_config_signal(
-+ const struct display_path *path,
-+ uint32_t idx);
-+
-+enum signal_type dal_display_path_get_query_signal(
-+ const struct display_path *path,
-+ uint32_t idx);
-+
-+struct link_service *dal_display_path_get_mst_link_service(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_sync_output_object(
-+ struct display_path *path,
-+ enum sync_source o_source,
-+ struct encoder *o_object);
-+
-+struct encoder *dal_display_path_get_sync_output_object(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_stereo_sync_object(
-+ struct display_path *path,
-+ struct encoder *stereo_sync);
-+
-+struct encoder *dal_display_path_get_stereo_sync_object(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_sync_input_source(
-+ struct display_path *path,
-+ enum sync_source s);
-+
-+enum sync_source dal_display_path_get_sync_input_source(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_sync_output_source(
-+ struct display_path *path,
-+ enum sync_source s);
-+
-+enum sync_source dal_display_path_get_sync_output_source(
-+ const struct display_path *path);
-+
-+bool dal_display_path_set_pixel_clock_safe_range(
-+ struct display_path *path,
-+ struct pixel_clock_safe_range *range);
-+
-+bool dal_display_path_get_pixel_clock_safe_range(
-+ const struct display_path *path,
-+ struct pixel_clock_safe_range *range);
-+
-+void dal_display_path_set_ddi_channel_mapping(
-+ struct display_path *path,
-+ union ddi_channel_mapping mapping);
-+
-+bool dal_display_path_set_sink_signal(
-+ struct display_path *path,
-+ enum signal_type sink_signal);
-+
-+enum signal_type dal_display_path_sink_signal_to_asic_signal(
-+ struct display_path *path,
-+ enum signal_type sink_signal);
-+
-+enum signal_type dal_display_path_sink_signal_to_link_signal(
-+ struct display_path *path,
-+ enum signal_type sink_signal,
-+ uint32_t idx);
-+
-+enum signal_type dal_display_path_downstream_to_upstream_signal(
-+ struct display_path *path,
-+ enum signal_type signal,
-+ uint32_t idx);
-+
-+bool dal_display_path_is_audio_present(
-+ const struct display_path *path,
-+ uint32_t *audio_pin);
-+
-+bool dal_display_path_is_dp_auth_supported(
-+ struct display_path *path);
-+
-+bool dal_display_path_is_vce_supported(
-+ const struct display_path *path);
-+
-+bool dal_display_path_is_sls_capable(
-+ const struct display_path *path);
-+
-+bool dal_display_path_is_gen_lock_capable(
-+ const struct display_path *path);
-+
-+struct transmitter_configuration dal_display_path_get_transmitter_configuration(
-+ const struct display_path *path,
-+ bool physical);
-+
-+bool dal_display_path_is_ss_supported(
-+ const struct display_path *path);
-+
-+bool dal_display_path_is_ss_configurable(
-+ const struct display_path *path);
-+
-+void dal_display_path_set_ss_support(
-+ struct display_path *path,
-+ bool s);
-+
-+enum signal_type dal_display_path_get_active_signal(
-+ struct display_path *path,
-+ uint32_t idx);
-+
-+bool dal_display_path_contains_object(
-+ struct display_path *path,
-+ struct graphics_object_id id);
-+
-+/* Multi-plane declarations.
-+ * This structure should also be used for Stereo. */
-+struct display_path_plane {
-+ struct controller *controller;
-+ /* During dal_tm_acquire_plane_resources() set blnd_mode, because
-+ * "layer index" is known at that point, and we must decide how
-+ * "controller" should do the blending */
-+ enum blender_mode blnd_mode;
-+ /* Some use-cases allow to power-gate FE.
-+ * For example, with Full Screen Video on Underlay we can
-+ * disable the 'root' plane.
-+ * This flag indicates that FE should be power-gated */
-+ bool disabled;
-+};
-+
-+bool dal_display_path_add_plane(
-+ struct display_path *path,
-+ struct display_path_plane *plane);
-+
-+uint8_t dal_display_path_get_number_of_planes(
-+ const struct display_path *path);
-+
-+struct display_path_plane *dal_display_path_get_plane_at_index(
-+ const struct display_path *path,
-+ uint8_t index);
-+
-+struct controller *dal_display_path_get_controller_for_layer_index(
-+ const struct display_path *path,
-+ uint8_t layer_index);
-+
-+void dal_display_path_release_planes(
-+ struct display_path *path);
-+
-+void dal_display_path_release_non_root_planes(
-+ struct display_path *path);
-+
-+#endif /* __DISPLAY_PATH_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/display_path_types.h b/drivers/gpu/drm/amd/dal/include/display_path_types.h
-new file mode 100644
-index 0000000..8aac46d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/display_path_types.h
-@@ -0,0 +1,132 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DISPLAY_PATH_TYPES_H__
-+#define __DAL_DISPLAY_PATH_TYPES_H__
-+
-+#include "grph_object_defs.h"
-+
-+enum {
-+ CONTROLLER_HANDLE_INVALID = (uint32_t) (-1)
-+};
-+
-+/*Limit maximum number of cofunctional paths*/
-+enum {
-+ MAX_COFUNCTIONAL_PATHS = 6
-+};
-+
-+struct pixel_clock_safe_range {
-+ uint32_t min_frequency;
-+ uint32_t max_frequency;
-+};
-+
-+/**
-+ * ClockSharingGroup
-+ * Enumeration of Clock Source Sharing categories
-+ * Instead using enum we define valid range for clock sharing group values
-+ * This is because potential num of group can be pretty big
-+ */
-+
-+enum clock_sharing_group {
-+ /* Default group for display paths that cannot share clock source.
-+ * Display path in such group will aqcuire clock source exclusively*/
-+ CLOCK_SHARING_GROUP_EXCLUSIVE = 0,
-+ /* DisplayPort paths will have this group if clock sharing
-+ * level is DisplayPortShareable*/
-+ CLOCK_SHARING_GROUP_DISPLAY_PORT = 1,
-+ /* Mst paths will have this group if clock sharing
-+ * level is DpMstShareable*/
-+ CLOCK_SHARING_GROUP_DP_MST = 2,
-+ /* Display paths will have this group when
-+ * desired to use alternative DPRef clock source.*/
-+ CLOCK_SHARING_GROUP_ALTERNATIVE_DP_REF = 3,
-+ /* Start of generic SW sharing groups.*/
-+ CLOCK_SHARING_GROUP_GROUP1 = 4,
-+ /* Total number of clock sharing groups.*/
-+ CLOCK_SHARING_GROUP_MAX = 32,
-+};
-+/* Should be around maximal number of ever connected displays (since boot :)*/
-+/*TEMP*/
-+enum goc_link_settings_type {
-+ GOC_LINK_SETTINGS_TYPE_PREFERRED = 0,
-+ GOC_LINK_SETTINGS_TYPE_REPORTED,
-+ GOC_LINK_SETTINGS_TYPE_TRAINED,
-+ GOC_LINK_SETTINGS_TYPE_OVERRIDEN_TRAINED,
-+ GOC_LINK_SETTINGS_TYPE_MAX
-+};
-+
-+struct dp_audio_test_data {
-+
-+ struct dp_audio_test_data_flags {
-+ uint32_t test_requested:1;
-+ uint32_t disable_video:1;
-+ } flags;
-+
-+ /*struct dp_audio_test_data_flags flags;*/
-+ uint32_t sampling_rate;
-+ uint32_t channel_count;
-+ uint32_t pattern_type;
-+ uint8_t pattern_period[8];
-+};
-+
-+struct goc_link_service_data {
-+ struct dp_audio_test_data dp_audio_test_data;
-+};
-+/* END-OF-TEMP*/
-+
-+
-+union display_path_properties {
-+ struct bit_map {
-+ uint32_t ALWAYS_CONNECTED:1;
-+ uint32_t HPD_SUPPORTED:1;
-+ uint32_t NON_DESTRUCTIVE_POLLING:1;
-+ uint32_t FORCE_CONNECT_SUPPORTED:1;
-+ uint32_t FAKED_PATH:1;
-+ uint32_t IS_BRANCH_DP_MST_PATH:1;
-+ uint32_t IS_ROOT_DP_MST_PATH:1;
-+ uint32_t IS_DP_AUDIO_SUPPORTED:1;
-+ uint32_t IS_HDMI_AUDIO_SUPPORTED:1;
-+ } bits;
-+
-+ uint32_t raw;
-+};
-+
-+enum display_tri_state {
-+ DISPLAY_TRI_STATE_UNKNOWN = 0,
-+ DISPLAY_TRI_STATE_TRUE,
-+ DISPLAY_TRI_STATE_FALSE
-+};
-+
-+enum {
-+ MAX_NUM_OF_LINKS_PER_PATH = 2
-+};
-+enum {
-+ SINK_LINK_INDEX = (uint32_t) (-1)
-+};
-+enum {
-+ ASIC_LINK_INDEX = 0
-+};
-+
-+#endif /* __DAL_DISPLAY_PATH_TYPES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/display_service_interface.h b/drivers/gpu/drm/amd/dal/include/display_service_interface.h
-new file mode 100644
-index 0000000..b602bca
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/display_service_interface.h
-@@ -0,0 +1,165 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DISPLAY_SERVICE_INTERFACE_H__
-+#define __DISPLAY_SERVICE_INTERFACE_H__
-+
-+#include "include/display_service_types.h"
-+#include "include/display_path_types.h"
-+#include "include/grph_object_ctrl_defs.h"
-+
-+struct display_service;
-+struct ds_overlay;
-+struct ds_dispatch;
-+struct ds_synchronization;
-+struct path_mode_set;
-+
-+struct display_service *dal_display_service_create(
-+ struct ds_init_data *data);
-+
-+void dal_display_service_destroy(
-+ struct display_service **ds);
-+
-+struct ds_dispatch *dal_display_service_get_adjustment_interface(
-+ struct display_service *ds);
-+
-+struct ds_overlay *dal_display_service_get_overlay_interface(
-+ struct display_service *ds);
-+
-+struct ds_dispatch *dal_display_service_get_set_mode_interface(
-+ struct display_service *ds);
-+
-+struct ds_dispatch *dal_display_service_get_reset_mode_interface(
-+ struct display_service *ds);
-+
-+struct ds_synchronization *dal_display_service_get_synchronization_interface(
-+ struct display_service *ds);
-+
-+enum ds_return dal_display_service_notify_v_sync_int_state(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ bool maintain_v_sync_phase);
-+
-+enum ds_return dal_display_service_target_power_control(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ bool power_on);
-+
-+enum ds_return dal_display_service_power_down_active_hw(
-+ struct display_service *ds,
-+ enum dc_video_power_state state);
-+
-+enum ds_return dal_display_service_mem_request_control(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ bool enable);
-+
-+enum ds_return dal_display_service_set_multimedia_pass_through_mode(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ bool passThrough);
-+
-+enum ds_return dal_display_service_set_palette(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ const struct ds_devclut *palette,
-+ const uint32_t start,
-+ const uint32_t length);
-+
-+enum ds_return dal_display_service_apply_pix_clk_range(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ struct pixel_clock_safe_range *range);
-+
-+enum ds_return dal_display_service_get_safe_pix_clk(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ uint32_t *pix_clk_khz);
-+
-+enum ds_return dal_display_service_apply_refreshrate_adjustment(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ enum ds_refreshrate_adjust_action action,
-+ struct ds_refreshrate *refreshrate);
-+
-+enum ds_return dal_display_service_pre_ddc(
-+ struct display_service *ds,
-+ uint32_t display_index);
-+
-+enum ds_return dal_display_service_post_ddc(
-+ struct display_service *ds,
-+ uint32_t display_index);
-+
-+enum ds_return dal_display_service_backlight_control(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ bool enable);
-+
-+enum ds_return dal_display_service_get_backlight_user_level(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ uint32_t *level);
-+
-+enum ds_return dal_display_service_get_backlight_effective_level(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ uint32_t *level);
-+
-+enum ds_return dal_display_service_enable_hpd(
-+ struct display_service *ds,
-+ uint32_t display_index);
-+
-+enum ds_return dal_display_service_disable_hpd(
-+ struct display_service *ds,
-+ uint32_t display_index);
-+
-+enum ds_return dal_display_service_get_min_mem_channels(
-+ struct display_service *ds,
-+ const struct path_mode_set *path_mode_set,
-+ uint32_t mem_channels_num,
-+ uint32_t *min_mem_channels_num);
-+
-+enum ds_return dal_display_service_enable_advanced_request(
-+ struct display_service *ds,
-+ bool enable);
-+
-+/*Audio related*/
-+enum ds_return dal_display_service_enable_audio_endpoint(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ bool enable);
-+
-+enum ds_return dal_display_service_mute_audio_endpoint(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ bool mute);
-+
-+bool dal_display_service_calc_view_port_for_wide_display(
-+ struct display_service *ds,
-+ uint32_t display_index,
-+ const struct ds_view_port *set_view_port,
-+ struct ds_get_view_port *get_view_port);
-+
-+#endif /* __DISPLAY_SERVICE_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/display_service_types.h b/drivers/gpu/drm/amd/dal/include/display_service_types.h
-new file mode 100644
-index 0000000..4f27f59
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/display_service_types.h
-@@ -0,0 +1,167 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DISPLAY_SERVICE_TYPES_H__
-+#define __DAL_DISPLAY_SERVICE_TYPES_H__
-+struct ds_dispatch {
-+
-+};
-+
-+struct ds_view_port_alignment {
-+ uint8_t x_width_size_alignment;
-+ uint8_t y_height_size_alignment;
-+ uint8_t x_start_alignment;
-+ uint8_t y_start_alignment;
-+};
-+
-+struct hw_sequencer;
-+struct topology_mgr;
-+struct adapter_service;
-+struct timing_service;
-+
-+struct ds_init_data {
-+ struct dal_context *dal_context;
-+ struct hw_sequencer *hwss;
-+ struct topology_mgr *tm;
-+ struct adapter_service *as;
-+ struct timing_service *ts;
-+ struct ds_view_port_alignment view_port_alignment;
-+};
-+
-+enum ds_return {
-+ DS_SUCCESS,
-+ DS_SUCCESS_FALLBACK,
-+ DS_ERROR,
-+ DS_SET_MODE_REQUIRED,
-+ DS_REBOOT_REQUIRED,
-+ DS_OUT_OF_RANGE,
-+ DS_RESOURCE_UNAVAILABLE,
-+ DS_NOT_SUPPORTED
-+};
-+
-+struct ds_devclut {
-+ uint8_t red;
-+ uint8_t green;
-+ uint8_t blue;
-+ uint8_t reserved;
-+};
-+
-+enum ds_refreshrate_adjust_action {
-+ DS_REFRESHRATE_ADJUST_ACTION_SET,
-+ DS_REFRESHRATE_ADJUST_ACTION_RESET,
-+ DS_REFRESHRATE_ADJUST_ACTION_UPDATE,
-+};
-+
-+struct ds_refreshrate {
-+ uint32_t numerator;
-+ uint32_t denominator;
-+};
-+
-+/*Contains delta in pixels between two active CRTC timings and relevant timing
-+details. Delta will be positive if CRTC1 timing running before CRTC2 and
-+negative otherwise (CRTC2 timing running before CRTC1)*/
-+/*CRTC1 running before CRTC2 = CRTC1 pixel position in
-+frame smaller then CRTC2 position*/
-+struct ds_timings_delta_info {
-+ int32_t delta_in_pixels;
-+ uint32_t pix_clk_khz;
-+ uint32_t h_total;
-+ uint32_t v_total;
-+};
-+
-+enum ds_audio_os_channel_name {
-+ DS_AUDIO_OS_CHANNEL_L = 0,
-+ DS_AUDIO_OS_CHANNEL_R = 1,
-+ DS_AUDIO_OS_CHANNEL_C = 2,
-+ DS_AUDIO_OS_CHANNEL_SUB = 3,
-+ DS_AUDIO_OS_CHANNEL_RL = 4,
-+ DS_AUDIO_OS_CHANNEL_RR = 5,
-+ DS_AUDIO_OS_CHANNEL_SL = 6,
-+ DS_AUDIO_OS_CHANNEL_SR = 7,
-+ DS_AUDIO_OS_CHANNEL_SILENT = 8,
-+ DS_AUDIO_OS_CHANNEL_NO_ASSOCIATION = 15
-+};
-+
-+enum ds_audio_azalia_channel_name {
-+ DS_AUDIO_AZALIA_CHANNEL_FL = 0,
-+ DS_AUDIO_AZALIA_CHANNEL_FR = 1,
-+ DS_AUDIO_AZALIA_CHANNEL_FC = 2,
-+ DS_AUDIO_AZALIA_CHANNEL_SUB = 3,
-+ DS_AUDIO_AZALIA_CHANNEL_SL = 4,
-+ DS_AUDIO_AZALIA_CHANNEL_SR = 5,
-+ DS_AUDIO_AZALIA_CHANNEL_BL = 6,
-+ DS_AUDIO_AZALIA_CHANNEL_BR = 7,
-+ DS_AUDIO_AZALIA_CHANNEL_SILENT = 8,
-+ DS_AUDIO_AZALIA_CHANNEL_NO_ASSOCIATION = 15
-+};
-+
-+enum ds_audio_channel_format {
-+ DS_AUDIO_CHANNEL_FORMAT_2P0 = 0,
-+ DS_AUDIO_CHANNEL_FORMAT_2P1,
-+ DS_AUDIO_CHANNEL_FORMAT_5P1,
-+ DS_AUDIO_CHANNEL_FORMAT_7P1
-+};
-+
-+/*Used for get/set Mirabilis*/
-+enum ds_mirabilis_control_option {
-+ DS_MIRABILIS_UNINITIALIZE = 0,
-+ DS_MIRABILIS_DISABLE,
-+ DS_MIRABILIS_ENABLE,
-+ DS_MIRABILIS_SAVE_PROFILE
-+};
-+
-+struct ds_disp_identifier {
-+ uint32_t display_index;
-+ uint32_t manufacture_id;
-+ uint32_t product_id;
-+ uint32_t serial_no;
-+};
-+
-+struct ds_view_port {
-+ uint32_t x_start;
-+ uint32_t y_start;
-+ uint32_t width;
-+ uint32_t height;
-+ uint32_t controller;
-+};
-+
-+#define DS_MAX_NUM_VIEW_PORTS 2
-+struct ds_get_view_port {
-+ uint32_t num_of_view_ports;
-+ struct ds_view_port view_ports[DS_MAX_NUM_VIEW_PORTS];
-+};
-+
-+struct ranged_timing_preference_flags {
-+ union {
-+ struct {
-+ uint32_t prefer_enable_drr:1;
-+ uint32_t force_disable_drr:1;
-+
-+ } bits;
-+ uint32_t u32all;
-+ };
-+};
-+
-+#endif /* __DAL_DISPLAY_SERVICE_TYPE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/dmcu_interface.h b/drivers/gpu/drm/amd/dal/include/dmcu_interface.h
-new file mode 100644
-index 0000000..c712cc2
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/dmcu_interface.h
-@@ -0,0 +1,87 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DMCU_INTERFACE_H__
-+#define __DAL_DMCU_INTERFACE_H__
-+
-+#include "grph_object_defs.h"
-+#include "dmcu_types.h"
-+
-+/* Interface functions */
-+
-+/* DMCU setup related interface functions */
-+struct dmcu *dal_dmcu_create(
-+ struct dmcu_init_data *init_data);
-+void dal_dmcu_destroy(struct dmcu **dmcu);
-+void dal_dmcu_release_hw(struct dmcu *dmcu);
-+
-+void dal_dmcu_power_up(struct dmcu *dmcu);
-+void dal_dmcu_power_down(struct dmcu *dmcu);
-+
-+void dal_dmcu_configure_wait_loop(
-+ struct dmcu *dmcu,
-+ uint32_t display_clock);
-+
-+/* PSR feature related interface functions */
-+void dal_dmcu_psr_setup(
-+ struct dmcu *dmcu,
-+ struct dmcu_context *dmcu_context);
-+void dal_dmcu_psr_enable(struct dmcu *dmcu);
-+void dal_dmcu_psr_disable(struct dmcu *dmcu);
-+void dal_dmcu_psr_block(struct dmcu *dmcu, bool block_psr);
-+bool dal_dmcu_psr_is_blocked(struct dmcu *dmcu);
-+void dal_dmcu_psr_set_level(
-+ struct dmcu *dmcu,
-+ union dmcu_psr_level psr_level);
-+void dal_dmcu_psr_allow_power_down_crtc(
-+ struct dmcu *dmcu,
-+ bool should_allow_crtc_power_down);
-+bool dal_dmcu_psr_submit_command(
-+ struct dmcu *dmcu,
-+ struct dmcu_context *dmcu_context,
-+ struct dmcu_config_data *config_data);
-+void dal_dmcu_psr_get_config_data(
-+ struct dmcu *dmcu,
-+ uint32_t v_total,
-+ struct dmcu_config_data *config_data);
-+
-+/* ABM feature related interface functions */
-+void dal_dmcu_abm_enable(
-+ struct dmcu *dmcu,
-+ enum controller_id controller_id,
-+ uint32_t vsync_rate_hz);
-+void dal_dmcu_abm_disable(struct dmcu *dmcu);
-+bool dal_dmcu_abm_enable_smooth_brightness(struct dmcu *dmcu);
-+bool dal_dmcu_abm_disable_smooth_brightness(struct dmcu *dmcu);
-+void dal_dmcu_abm_varibright_control(
-+ struct dmcu *dmcu,
-+ const struct varibright_control *varibright_control);
-+bool dal_dmcu_abm_set_backlight_level(
-+ struct dmcu *dmcu,
-+ uint8_t backlight_8_bit);
-+uint8_t dal_dmcu_abm_get_user_backlight_level(struct dmcu *dmcu);
-+uint8_t dal_dmcu_abm_get_current_backlight_level(struct dmcu *dmcu);
-+
-+#endif /* __DAL_DMCU_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/dmcu_types.h b/drivers/gpu/drm/amd/dal/include/dmcu_types.h
-new file mode 100644
-index 0000000..1f3107d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/dmcu_types.h
-@@ -0,0 +1,199 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DMCU_TYPES_H__
-+#define __DAL_DMCU_TYPES_H__
-+
-+/* Forward declaration */
-+struct dmcu;
-+
-+/* Required information for creation and initialization of a controller */
-+struct dmcu_init_data {
-+ struct dal_context *dal_context;
-+ struct adapter_service *as;
-+ uint32_t max_engine_clock_in_khz;
-+};
-+
-+/* Interface structure defines */
-+
-+enum dmcu_action {
-+ DMCU_ACTION_PSR_ENABLE,
-+ DMCU_ACTION_PSR_EXIT,
-+ DMCU_ACTION_PSR_RFB_UPDATE,
-+ DMCU_ACTION_PSR_SET,
-+ DMCU_ACTION_PSR_CLEAR_COUNT,
-+ DMCU_ACTION_PSR_COUNT_REQUEST,
-+ DMCU_ACTION_PSR_STATE_REQUEST,
-+ DMCU_ACTION_PSR_SET_LEVEL,
-+ DMCU_ACTION_PSR_ADVANCE_STATE,
-+ DMCU_ACTION_PSR_SET_WAITLOOP
-+};
-+
-+enum dmcu_output {
-+ DMCU_OUTPUT_PSR_ACK,
-+ DMCU_OUTPUT_PSR_NACK,
-+ DMCU_OUTPUT_PSR_AUX_ERR,
-+ DMCU_OUTPUT_PSR_COUNT_STATUS,
-+ DMCU_OUTPUT_PSR_STATE_STATUS,
-+ DMCU_OUTPUT_PSR_RFB_UPDATE_ERR,
-+ DMCU_OUTPUT_PSR_ERR,
-+ DMCU_OUTPUT_PSR_GET_REPLY,
-+ DMCU_OUTPUT_PSR_ENTRY_ERROR,
-+ DMCU_OUTPUT_PSR_LT_ERROR,
-+ DMCU_OUTPUT_PSR_FORCE_SR_ERROR,
-+ DMCU_OUTPUT_PSR_SDP_SEND_TIMEOUT
-+};
-+
-+/* PSR states, based similarly on states defined in eDP specification. */
-+enum psr_state {
-+ STATE0, /* PSR is disabled */
-+ STATE1, /* PSR is enabled, but inactive */
-+ STATE1A,
-+ STATE2, /* PSR is transitioning to active state */
-+ STATE2A,
-+ STATE3, /* PSR is active; Display is in self refresh */
-+ STATE3INIT,
-+ STATE4, /* RFB single frame update */
-+ STATE4A,
-+ STATE4B,
-+ STATE4C,
-+ STATE4D,
-+ STATE5, /* Exiting from PSR active state */
-+ STATE5A,
-+ STATE5B,
-+ STATE5C
-+};
-+
-+enum phy_type {
-+ PHY_TYPE_UNKNOWN = 1,
-+ PHY_TYPE_PCIE_PHY = 2,
-+ PHY_TYPE_UNIPHY = 3,
-+};
-+
-+struct dmcu_context {
-+ enum channel_id channel;
-+ enum transmitter transmitter_id;
-+ enum engine_id engine_id;
-+ enum controller_id controller_id;
-+ enum phy_type phy_type;
-+ enum physical_phy_id smu_physical_phy_id;
-+
-+ /* Vertical total pixels from crtc timing.
-+ * This is used for static screen detection.
-+ * ie. If we want to detect half a frame,
-+ * we use this to determine the hyst lines.*/
-+ uint32_t crtc_timing_vertical_total;
-+
-+ /* PSR supported from panel capabilities
-+ * and current display configuration */
-+ bool psr_supported_display_config;
-+
-+ /* Whether fast link training is supported by the panel */
-+ bool psr_exit_link_training_required;
-+
-+ /* If RFB setup time is greater than the total VBLANK time, it is not
-+ * possible for the sink to capture the video frame in the same frame
-+ * the SDP is sent. In this case, the frame capture indication bit
-+ * should be set and an extra static frame should be transmitted to
-+ * the sink */
-+ bool psr_frame_capture_indication_required;
-+
-+ /* Set the last possible line SDP may be transmitted without violating
-+ * the RFB setup time */
-+ bool sdp_transmit_line_num_deadline;
-+
-+ /* The VSync rate in Hz used to calculate the step size
-+ * for smooth brightness feature */
-+ uint32_t vsync_rate_hz;
-+};
-+
-+union dmcu_psr_level {
-+ struct {
-+ bool SKIP_CRC:1;
-+ bool SKIP_DP_VID_STREAM_DISABLE:1;
-+ bool SKIP_PHY_POWER_DOWN:1;
-+ bool SKIP_AUX_ACK_CHECK:1;
-+ bool SKIP_CRTC_DISABLE:1;
-+ bool SKIP_AUX_RFB_CAPTURE_CHECK:1;
-+ bool SKIP_SMU_NOTIFICATION:1;
-+ bool SKIP_AUTO_STATE_ADVANCE:1;
-+ bool DISABLE_PSR_ENTRY_ABORT:1;
-+ } bits;
-+ uint32_t u32all;
-+};
-+
-+struct dmcu_config_data {
-+ /* Command sent to DMCU. */
-+ enum dmcu_action action;
-+ /* PSR Level controls which HW blocks to power down during PSR active,
-+ * and also other sequence modifications. */
-+ union dmcu_psr_level psr_level;
-+ /* To indicate that first changed frame from active state should not
-+ * result in exit to inactive state, but instead perform an automatic
-+ * single frame RFB update. */
-+ bool rfb_update_auto_en;
-+ /* Number of consecutive static frames to detect before entering PSR
-+ * active state. */
-+ uint32_t hyst_frames;
-+ /* Partial frames before entering PSR active. Note this parameter is in
-+ * units of 100 lines. i.e. Wait a value of 5 means wait 500 additional
-+ * lines. */
-+ uint32_t hyst_lines;
-+ /* Number of repeated AUX retries before indicating failure to driver.
-+ * In a working case, first attempt to write/read AUX should pass. */
-+ uint32_t aux_repeat;
-+ /* Additional delay after remote frame capture before continuing to
-+ * power down. This is mainly for debug purposes to identify timing
-+ * issues. */
-+ uint32_t frame_delay;
-+ /* Controls how long the delay of a wait loop is. It should be tuned
-+ * to 1 us, and needs to be reconfigured every time DISPCLK changes. */
-+ uint32_t wait_loop_num;
-+};
-+
-+struct dmcu_output_data {
-+ /* DMCU reply */
-+ enum dmcu_output output;
-+ /* The current PSR state. */
-+ uint32_t psr_state;
-+ /* The number of frames during PSR active state. */
-+ uint32_t psr_count;
-+};
-+
-+enum varibright_command {
-+ VARIBRIGHT_CMD_SET_VB_LEVEL = 0,
-+ VARIBRIGHT_CMD_USER_ENABLE,
-+ VARIBRIGHT_CMD_POST_DISPLAY_CONFIG,
-+ VARIBRIGHT_CMD_UNKNOWN
-+};
-+
-+struct varibright_control {
-+ enum varibright_command command;
-+ uint8_t level;
-+ bool enable;
-+ bool activate;
-+};
-+
-+#endif /* __DAL_DMCU_TYPES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/dpcd_access_service_interface.h b/drivers/gpu/drm/amd/dal/include/dpcd_access_service_interface.h
-new file mode 100644
-index 0000000..a942c77
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/dpcd_access_service_interface.h
-@@ -0,0 +1,65 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifdef __DPCD_ACCESS_SERVICE_INTERFACE_HPP__
-+#define __DPCD_ACCESS_SERVICE_INTERFACE_HPP__
-+
-+/* DDC service transaction error codes
-+ * depends on transaction status
-+ */
-+enum ddc_result {
-+ DDCRESULT_UNKNOWN = 0,
-+ DDCRESULT_SUCESSFULL,
-+ DDCRESULT_FAILEDCHANNELBUSY,
-+ DDCRESULT_FAILEDTIMEOUT,
-+ DDCRESULT_FAILEDPROTOCOLERROR,
-+ DDCRESULT_FAILEDNACK,
-+ DDCRESULT_FAILEDINCOMPLETE,
-+ DDCRESULT_FAILEDOPERATION,
-+ DDCRESULT_FAILEDINVALIDOPERATION,
-+ DDCRESULT_FAILEDBUFFEROVERFLOW
-+};
-+
-+enum {
-+ MaxNativeAuxTransactionSize = 16
-+};
-+
-+struct display_sink_capability;
-+
-+/* TO DO: below functions can be moved to ddc_service (think about it)*/
-+enum ddc_result dal_ddc_read_dpcd_data(
-+ uint32_t address,
-+ unsigned char *data,
-+ uint32_t size);
-+
-+enum ddc_result dal_ddc_write_dpcd_data(
-+ uint32_t address,
-+ const unsigned char *data uint32_t size);
-+
-+bool dal_aux_query_dp_sink_capability(display_sink_capability *sink_cap);
-+bool start_gtc_sync(void);
-+bool stop_gtc_sync(void);
-+
-+#endif /*__DPCD_ACCESS_SERVICE_INTERFACE_HPP__*/
-diff --git a/drivers/gpu/drm/amd/dal/include/dpcd_defs.h b/drivers/gpu/drm/amd/dal/include/dpcd_defs.h
-new file mode 100644
-index 0000000..cefa1fc
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/dpcd_defs.h
-@@ -0,0 +1,869 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DPCD_DEFS_H__
-+#define __DAL_DPCD_DEFS_H__
-+
-+enum dpcd_address {
-+/* addresses marked with 1.2 are only defined since DP 1.2 spec */
-+
-+ /* Reciever Capability Field */
-+ DPCD_ADDRESS_DPCD_REV = 0x00000,
-+ DPCD_ADDRESS_MAX_LINK_RATE = 0x00001,
-+ DPCD_ADDRESS_MAX_LANE_COUNT = 0x00002,
-+ DPCD_ADDRESS_MAX_DOWNSPREAD = 0x00003,
-+ DPCD_ADDRESS_NORP = 0x00004,
-+ DPCD_ADDRESS_DOWNSTREAM_PORT_PRESENT = 0x00005,
-+ DPCD_ADDRESS_MAIN_LINK_CHANNEL_CODING = 0x00006,
-+ DPCD_ADDRESS_DOWNSTREAM_PORT_COUNT = 0x00007,
-+ DPCD_ADDRESS_RECEIVE_PORT0_CAP0 = 0x00008,
-+ DPCD_ADDRESS_RECEIVE_PORT0_CAP1 = 0x00009,
-+ DPCD_ADDRESS_RECEIVE_PORT1_CAP0 = 0x0000A,
-+ DPCD_ADDRESS_RECEIVE_PORT1_CAP1 = 0x0000B,
-+
-+ DPCD_ADDRESS_I2C_SPEED_CNTL_CAP = 0x0000C,/*1.2*/
-+ DPCD_ADDRESS_EDP_CONFIG_CAP = 0x0000D,/*1.2*/
-+ DPCD_ADDRESS_TRAINING_AUX_RD_INTERVAL = 0x000E,/*1.2*/
-+
-+ DPCD_ADDRESS_MSTM_CAP = 0x00021,/*1.2*/
-+
-+ /* Audio Video Sync Data Feild */
-+ DPCD_ADDRESS_AV_GRANULARITY = 0x0023,
-+ DPCD_ADDRESS_AUDIO_DECODE_LATENCY1 = 0x0024,
-+ DPCD_ADDRESS_AUDIO_DECODE_LATENCY2 = 0x0025,
-+ DPCD_ADDRESS_AUDIO_POSTPROCESSING_LATENCY1 = 0x0026,
-+ DPCD_ADDRESS_AUDIO_POSTPROCESSING_LATENCY2 = 0x0027,
-+ DPCD_ADDRESS_VIDEO_INTERLACED_LATENCY = 0x0028,
-+ DPCD_ADDRESS_VIDEO_PROGRESSIVE_LATENCY = 0x0029,
-+ DPCD_ADDRESS_AUDIO_DELAY_INSERT1 = 0x0002B,
-+ DPCD_ADDRESS_AUDIO_DELAY_INSERT2 = 0x0002C,
-+ DPCD_ADDRESS_AUDIO_DELAY_INSERT3 = 0x0002D,
-+
-+ /* Audio capability */
-+ DPCD_ADDRESS_NUM_OF_AUDIO_ENDPOINTS = 0x00022,
-+
-+ DPCD_ADDRESS_GUID_START = 0x00030,/*1.2*/
-+ DPCD_ADDRESS_GUID_END = 0x0003f,/*1.2*/
-+
-+ DPCD_ADDRESS_PSR_SUPPORT_VER = 0x00070,
-+ DPCD_ADDRESS_PSR_CAPABILITY = 0x00071,
-+
-+ DPCD_ADDRESS_DWN_STRM_PORT0_CAPS = 0x00080,/*1.2a*/
-+
-+ /* Link Configuration Field */
-+ DPCD_ADDRESS_LINK_BW_SET = 0x00100,
-+ DPCD_ADDRESS_LANE_COUNT_SET = 0x00101,
-+ DPCD_ADDRESS_TRAINING_PATTERN_SET = 0x00102,
-+ DPCD_ADDRESS_LANE0_SET = 0x00103,
-+ DPCD_ADDRESS_LANE1_SET = 0x00104,
-+ DPCD_ADDRESS_LANE2_SET = 0x00105,
-+ DPCD_ADDRESS_LANE3_SET = 0x00106,
-+ DPCD_ADDRESS_DOWNSPREAD_CNTL = 0x00107,
-+ DPCD_ADDRESS_I2C_SPEED_CNTL = 0x00109,/*1.2*/
-+
-+ DPCD_ADDRESS_EDP_CONFIG_SET = 0x0010A,
-+ DPCD_ADDRESS_LINK_QUAL_LANE0_SET = 0x0010B,
-+ DPCD_ADDRESS_LINK_QUAL_LANE1_SET = 0x0010C,
-+ DPCD_ADDRESS_LINK_QUAL_LANE2_SET = 0x0010D,
-+ DPCD_ADDRESS_LINK_QUAL_LANE3_SET = 0x0010E,
-+
-+ DPCD_ADDRESS_LANE0_SET2 = 0x0010F,/*1.2*/
-+ DPCD_ADDRESS_LANE2_SET2 = 0x00110,/*1.2*/
-+
-+ DPCD_ADDRESS_MSTM_CNTL = 0x00111,/*1.2*/
-+
-+ DPCD_ADDRESS_PSR_ENABLE_CFG = 0x0170,
-+
-+ /* Payload Table Configuration Field 1.2 */
-+ DPCD_ADDRESS_PAYLOAD_ALLOCATE_SET = 0x001C0,
-+ DPCD_ADDRESS_PAYLOAD_ALLOCATE_START_TIMESLOT = 0x001C1,
-+ DPCD_ADDRESS_PAYLOAD_ALLOCATE_TIMESLOT_COUNT = 0x001C2,
-+
-+ DPCD_ADDRESS_SINK_COUNT = 0x0200,
-+ DPCD_ADDRESS_DEVICE_SERVICE_IRQ_VECTOR = 0x0201,
-+
-+ /* Link / Sink Status Field */
-+ DPCD_ADDRESS_LANE_01_STATUS = 0x00202,
-+ DPCD_ADDRESS_LANE_23_STATUS = 0x00203,
-+ DPCD_ADDRESS_LANE_ALIGN_STATUS_UPDATED = 0x0204,
-+ DPCD_ADDRESS_SINK_STATUS = 0x0205,
-+
-+ /* Adjust Request Field */
-+ DPCD_ADDRESS_ADJUST_REQUEST_LANE0_1 = 0x0206,
-+ DPCD_ADDRESS_ADJUST_REQUEST_LANE2_3 = 0x0207,
-+ DPCD_ADDRESS_ADJUST_REQUEST_POST_CURSOR2 = 0x020C,
-+
-+ /* Test Request Field */
-+ DPCD_ADDRESS_TEST_REQUEST = 0x0218,
-+ DPCD_ADDRESS_TEST_LINK_RATE = 0x0219,
-+ DPCD_ADDRESS_TEST_LANE_COUNT = 0x0220,
-+ DPCD_ADDRESS_TEST_PATTERN = 0x0221,
-+ DPCD_ADDRESS_TEST_MISC1 = 0x0232,
-+
-+ /* Phy Test Pattern Field */
-+ DPCD_ADDRESS_TEST_PHY_PATTERN = 0x0248,
-+ DPCD_ADDRESS_TEST_80BIT_CUSTOM_PATTERN_7_0 = 0x0250,
-+ DPCD_ADDRESS_TEST_80BIT_CUSTOM_PATTERN_15_8 = 0x0251,
-+ DPCD_ADDRESS_TEST_80BIT_CUSTOM_PATTERN_23_16 = 0x0252,
-+ DPCD_ADDRESS_TEST_80BIT_CUSTOM_PATTERN_31_24 = 0x0253,
-+ DPCD_ADDRESS_TEST_80BIT_CUSTOM_PATTERN_39_32 = 0x0254,
-+ DPCD_ADDRESS_TEST_80BIT_CUSTOM_PATTERN_47_40 = 0x0255,
-+ DPCD_ADDRESS_TEST_80BIT_CUSTOM_PATTERN_55_48 = 0x0256,
-+ DPCD_ADDRESS_TEST_80BIT_CUSTOM_PATTERN_63_56 = 0x0257,
-+ DPCD_ADDRESS_TEST_80BIT_CUSTOM_PATTERN_71_64 = 0x0258,
-+ DPCD_ADDRESS_TEST_80BIT_CUSTOM_PATTERN_79_72 = 0x0259,
-+
-+ /* Test Response Field*/
-+ DPCD_ADDRESS_TEST_RESPONSE = 0x0260,
-+
-+ /* Audio Test Pattern Field 1.2*/
-+ DPCD_ADDRESS_TEST_AUDIO_MODE = 0x0271,
-+ DPCD_ADDRESS_TEST_AUDIO_PATTERN_TYPE = 0x0272,
-+ DPCD_ADDRESS_TEST_AUDIO_PERIOD_CH_1 = 0x0273,
-+ DPCD_ADDRESS_TEST_AUDIO_PERIOD_CH_2 = 0x0274,
-+ DPCD_ADDRESS_TEST_AUDIO_PERIOD_CH_3 = 0x0275,
-+ DPCD_ADDRESS_TEST_AUDIO_PERIOD_CH_4 = 0x0276,
-+ DPCD_ADDRESS_TEST_AUDIO_PERIOD_CH_5 = 0x0277,
-+ DPCD_ADDRESS_TEST_AUDIO_PERIOD_CH_6 = 0x0278,
-+ DPCD_ADDRESS_TEST_AUDIO_PERIOD_CH_7 = 0x0279,
-+ DPCD_ADDRESS_TEST_AUDIO_PERIOD_CH_8 = 0x027A,
-+
-+ /* Payload Table Status Field */
-+ DPCD_ADDRESS_PAYLOAD_TABLE_UPDATE_STATUS = 0x002C0,/*1.2*/
-+ DPCD_ADDRESS_VC_PAYLOAD_ID_SLOT1 = 0x002C1,/*1.2*/
-+ DPCD_ADDRESS_VC_PAYLOAD_ID_SLOT63 = 0x002FF,/*1.2*/
-+
-+ /* Source Device Specific Field */
-+ DPCD_ADDRESS_SOURCE_DEVICE_ID_START = 0x0300,
-+ DPCD_ADDRESS_SOURCE_DEVICE_ID_END = 0x0301,
-+ DPCD_ADDRESS_SOURCE_RESERVED_START = 0x030C,
-+ DPCD_ADDRESS_SOURCE_RESERVED_END = 0x03FF,
-+
-+ /* Sink Device Specific Field */
-+ DPCD_ADDRESS_SINK_DEVICE_ID_START = 0x0400,
-+ DPCD_ADDRESS_SINK_DEVICE_ID_END = 0x0402,
-+ DPCD_ADDRESS_SINK_DEVICE_STR_START = 0x0403,
-+ DPCD_ADDRESS_SINK_DEVICE_STR_END = 0x0408,
-+ DPCD_ADDRESS_SINK_REVISION_START = 0x409,
-+ DPCD_ADDRESS_SINK_REVISION_END = 0x40B,
-+
-+ /* Branch Device Specific Field */
-+ DPCD_ADDRESS_BRANCH_DEVICE_ID_START = 0x0500,
-+ DPCD_ADDRESS_BRANCH_DEVICE_ID_END = 0x0502,
-+ DPCD_ADDRESS_BRANCH_DEVICE_STR_START = 0x0503,
-+ DPCD_ADDRESS_BRANCH_DEVICE_STR_END = 0x0508,
-+
-+ DPCD_ADDRESS_POWER_STATE = 0x0600,
-+
-+ /* EDP related */
-+ DPCD_ADDRESS_EDP_REV = 0x0700,
-+ DPCD_ADDRESS_EDP_CAPABILITY = 0x0701,
-+ DPCD_ADDRESS_EDP_BACKLIGHT_ADJUST_CAP = 0x0702,
-+ DPCD_ADDRESS_EDP_GENERAL_CAP2 = 0x0703,
-+
-+ DPCD_ADDRESS_EDP_DISPLAY_CONTROL = 0x0720,
-+ DPCD_ADDRESS_EDP_BACKLIGHT_SET = 0x0721,
-+ DPCD_ADDRESS_EDP_BACKLIGHT_BRIGHTNESS_MSB = 0x0722,
-+ DPCD_ADDRESS_EDP_BACKLIGHT_BRIGHTNESS_LSB = 0x0723,
-+ DPCD_ADDRESS_EDP_PWMGEN_BIT_COUNT = 0x0724,
-+ DPCD_ADDRESS_EDP_PWMGEN_BIT_COUNT_CAP_MIN = 0x0725,
-+ DPCD_ADDRESS_EDP_PWMGEN_BIT_COUNT_CAP_MAX = 0x0726,
-+ DPCD_ADDRESS_EDP_BACKLIGHT_CONTROL_STATUS = 0x0727,
-+ DPCD_ADDRESS_EDP_BACKLIGHT_FREQ_SET = 0x0728,
-+ DPCD_ADDRESS_EDP_REVERVED = 0x0729,
-+ DPCD_ADDRESS_EDP_BACKLIGNT_FREQ_CAP_MIN_MSB = 0x072A,
-+ DPCD_ADDRESS_EDP_BACKLIGNT_FREQ_CAP_MIN_MID = 0x072B,
-+ DPCD_ADDRESS_EDP_BACKLIGNT_FREQ_CAP_MIN_LSB = 0x072C,
-+ DPCD_ADDRESS_EDP_BACKLIGNT_FREQ_CAP_MAX_MSB = 0x072D,
-+ DPCD_ADDRESS_EDP_BACKLIGNT_FREQ_CAP_MAX_MID = 0x072E,
-+ DPCD_ADDRESS_EDP_BACKLIGNT_FREQ_CAP_MAX_LSB = 0x072F,
-+
-+ DPCD_ADDRESS_EDP_DBC_MINIMUM_BRIGHTNESS_SET = 0x0732,
-+ DPCD_ADDRESS_EDP_DBC_MAXIMUM_BRIGHTNESS_SET = 0x0733,
-+
-+ /* Sideband MSG Buffers 1.2 */
-+ DPCD_ADDRESS_DOWN_REQ_START = 0x01000,
-+ DPCD_ADDRESS_DOWN_REQ_END = 0x011ff,
-+
-+ DPCD_ADDRESS_UP_REP_START = 0x01200,
-+ DPCD_ADDRESS_UP_REP_END = 0x013ff,
-+
-+ DPCD_ADDRESS_DOWN_REP_START = 0x01400,
-+ DPCD_ADDRESS_DOWN_REP_END = 0x015ff,
-+
-+ DPCD_ADDRESS_UP_REQ_START = 0x01600,
-+ DPCD_ADDRESS_UP_REQ_END = 0x017ff,
-+
-+ /* ESI (Event Status Indicator) Field 1.2 */
-+ DPCD_ADDRESS_SINK_COUNT_ESI = 0x02002,
-+ DPCD_ADDRESS_DEVICE_IRQ_ESI0 = 0x02003,
-+ DPCD_ADDRESS_DEVICE_IRQ_ESI1 = 0x02004,
-+ /*@todo move dpcd_address_Lane01Status back here*/
-+
-+ DPCD_ADDRESS_PSR_ERROR_STATUS = 0x2006,
-+ DPCD_ADDRESS_PSR_EVENT_STATUS = 0x2007,
-+ DPCD_ADDRESS_PSR_SINK_STATUS = 0x2008,
-+ DPCD_ADDRESS_PSR_DBG_REGISTER0 = 0x2009,
-+ DPCD_ADDRESS_PSR_DBG_REGISTER1 = 0x200A,
-+
-+ /* Travis specific addresses */
-+ DPCD_ADDRESS_TRAVIS_SINK_DEV_SEL = 0x5f0,
-+ DPCD_ADDRESS_TRAVIS_SINK_ACCESS_OFFSET = 0x5f1,
-+ DPCD_ADDRESS_TRAVIS_SINK_ACCESS_REG = 0x5f2,
-+};
-+
-+enum dpcd_revision {
-+ DPCD_REV_10 = 0x10,
-+ DPCD_REV_11 = 0x11,
-+ DPCD_REV_12 = 0x12
-+};
-+
-+enum dp_pwr_state {
-+ DP_PWR_STATE_D0 = 1,/* direct HW translation! */
-+ DP_PWR_STATE_D3
-+};
-+
-+/* these are the types stored at DOWNSTREAMPORT_PRESENT */
-+enum dpcd_downstream_port_type {
-+ DOWNSTREAM_DP = 0,
-+ DOWNSTREAM_VGA,
-+ DOWNSTREAM_DVI_HDMI,
-+ DOWNSTREAM_NONDDC /* has no EDID (TV,CV) */
-+};
-+
-+enum dpcd_link_test_patterns {
-+ LINK_TEST_PATTERN_NONE = 0,
-+ LINK_TEST_PATTERN_COLOR_RAMP,
-+ LINK_TEST_PATTERN_VERTICAL_BARS,
-+ LINK_TEST_PATTERN_COLOR_SQUARES
-+};
-+
-+enum dpcd_test_color_format {
-+ TEST_COLOR_FORMAT_RGB = 0,
-+ TEST_COLOR_FORMAT_YCBCR422,
-+ TEST_COLOR_FORMAT_YCBCR444
-+};
-+
-+enum dpcd_test_bit_depth {
-+ TEST_BIT_DEPTH_6 = 0,
-+ TEST_BIT_DEPTH_8,
-+ TEST_BIT_DEPTH_10,
-+ TEST_BIT_DEPTH_12,
-+ TEST_BIT_DEPTH_16
-+};
-+
-+/* PHY (encoder) test patterns
-+The order of test patterns follows DPCD register PHY_TEST_PATTERN (0x248) */
-+enum dpcd_phy_test_patterns {
-+ PHY_TEST_PATTERN_NONE = 0,
-+ PHY_TEST_PATTERN_D10_2,
-+ PHY_TEST_PATTERN_SYMBOL_ERROR,
-+ PHY_TEST_PATTERN_PRBS7,
-+ PHY_TEST_PATTERN_80BIT_CUSTOM,/* For DP1.2 only */
-+ PHY_TEST_PATTERN_HBR2_COMPLIANCE_EYE/* For DP1.2 only */
-+};
-+
-+enum dpcd_test_dyn_range {
-+ TEST_DYN_RANGE_VESA = 0,
-+ TEST_DYN_RANGE_CEA
-+};
-+
-+enum dpcd_audio_test_pattern {
-+ AUDIO_TEST_PATTERN_OPERATOR_DEFINED = 0,/* direct HW translation */
-+ AUDIO_TEST_PATTERN_SAWTOOTH
-+};
-+
-+enum dpcd_audio_sampling_rate {
-+ AUDIO_SAMPLING_RATE_32KHZ = 0,/* direct HW translation */
-+ AUDIO_SAMPLING_RATE_44_1KHZ,
-+ AUDIO_SAMPLING_RATE_48KHZ,
-+ AUDIO_SAMPLING_RATE_88_2KHZ,
-+ AUDIO_SAMPLING_RATE_96KHZ,
-+ AUDIO_SAMPLING_RATE_176_4KHZ,
-+ AUDIO_SAMPLING_RATE_192KHZ
-+};
-+
-+enum dpcd_audio_channels {
-+ AUDIO_CHANNELS_1 = 0,/* direct HW translation */
-+ AUDIO_CHANNELS_2,
-+ AUDIO_CHANNELS_3,
-+ AUDIO_CHANNELS_4,
-+ AUDIO_CHANNELS_5,
-+ AUDIO_CHANNELS_6,
-+ AUDIO_CHANNELS_7,
-+ AUDIO_CHANNELS_8,
-+
-+ AUDIO_CHANNELS_COUNT
-+};
-+
-+enum dpcd_audio_test_pattern_periods {
-+ DPCD_AUDIO_TEST_PATTERN_PERIOD_NOTUSED = 0,/* direct HW translation */
-+ DPCD_AUDIO_TEST_PATTERN_PERIOD_3,
-+ DPCD_AUDIO_TEST_PATTERN_PERIOD_6,
-+ DPCD_AUDIO_TEST_PATTERN_PERIOD_12,
-+ DPCD_AUDIO_TEST_PATTERN_PERIOD_24,
-+ DPCD_AUDIO_TEST_PATTERN_PERIOD_48,
-+ DPCD_AUDIO_TEST_PATTERN_PERIOD_96,
-+ DPCD_AUDIO_TEST_PATTERN_PERIOD_192,
-+ DPCD_AUDIO_TEST_PATTERN_PERIOD_384,
-+ DPCD_AUDIO_TEST_PATTERN_PERIOD_768,
-+ DPCD_AUDIO_TEST_PATTERN_PERIOD_1536
-+};
-+
-+/* This enum is for programming DPCD TRAINING_PATTERN_SET */
-+enum dpcd_training_patterns {
-+ DPCD_TRAINING_PATTERN_VIDEOIDLE = 0,/* direct HW translation! */
-+ DPCD_TRAINING_PATTERN_1,
-+ DPCD_TRAINING_PATTERN_2,
-+ DPCD_TRAINING_PATTERN_3
-+};
-+
-+/* This enum is for use with PsrSinkPsrStatus.bits.sinkSelfRefreshStatus
-+It defines the possible PSR states. */
-+enum dpcd_psr_sink_states {
-+ PSR_SINK_STATE_INACTIVE = 0,
-+ PSR_SINK_STATE_ACTIVE_CAPTURE_DISPLAY_ON_SOURCE_TIMING = 1,
-+ PSR_SINK_STATE_ACTIVE_DISPLAY_FROM_SINK_RFB = 2,
-+ PSR_SINK_STATE_ACTIVE_CAPTURE_DISPLAY_ON_SINK_TIMING = 3,
-+ PSR_SINK_STATE_ACTIVE_CAPTURE_TIMING_RESYNC = 4,
-+ PSR_SINK_STATE_SINK_INTERNAL_ERROR = 7,
-+};
-+
-+/* This enum defines the Panel's eDP revision at DPCD 700h
-+ * 00h = eDP v1.1 or lower
-+ * 01h = eDP v1.2
-+ * 02h = eDP v1.3 (PSR support starts here)
-+ * 03h = eDP v1.4
-+ * If unknown revision, treat as eDP v1.1, meaning least functionality set.
-+ * This enum has values matched to eDP spec, thus values should not change.
-+ */
-+enum dpcd_edp_revision {
-+ DPCD_EDP_REVISION_EDP_V1_1 = 0,
-+ DPCD_EDP_REVISION_EDP_V1_2 = 1,
-+ DPCD_EDP_REVISION_EDP_V1_3 = 2,
-+ DPCD_EDP_REVISION_EDP_V1_4 = 3,
-+ DPCD_EDP_REVISION_EDP_UNKNOWN = DPCD_EDP_REVISION_EDP_V1_1,
-+};
-+
-+union dpcd_rev {
-+ struct {
-+ uint8_t MINOR:4;
-+ uint8_t MAJOR:4;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union max_lane_count {
-+ struct {
-+ uint8_t MAX_LANE_COUNT:5;
-+ uint8_t POST_LT_ADJ_REQ_SUPPORTED:1;
-+ uint8_t TPS3_SUPPORTED:1;
-+ uint8_t ENHANCED_FRAME_CAP:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union max_down_spread {
-+ struct {
-+ uint8_t MAX_DOWN_SPREAD:1;
-+ uint8_t RESERVED:5;
-+ uint8_t NO_AUX_HANDSHAKE_LINK_TRAINING:1;
-+ uint8_t RESERVED1:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union mstm_cap {
-+ struct {
-+ uint8_t MST_CAP:1;
-+ uint8_t RESERVED:7;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union mstm_cntl {
-+ struct {
-+ uint8_t MST_EN:1;
-+ uint8_t UP_REQ_EN:1;
-+ uint8_t UPSTREAM_IS_SRC:1;
-+ uint8_t RESERVED:5;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union lane_count_set {
-+ struct {
-+ uint8_t LANE_COUNT_SET:5;
-+ uint8_t POST_LT_ADJ_REQ_GRANTED:1;
-+ uint8_t RESERVED:1;
-+ uint8_t ENHANCED_FRAMING:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+/* for DPCD_ADDRESS_I2C_SPEED_CNTL_CAP
-+ * and DPCD_ADDRESS_I2C_SPEED_CNTL
-+ */
-+union i2c_speed {
-+ struct {
-+ uint8_t _1KBPS:1;
-+ uint8_t _5KBPS:1;
-+ uint8_t _10KBPS:1;
-+ uint8_t _100KBPS:1;
-+ uint8_t _400KBPS:1;
-+ uint8_t _1MBPS:1;
-+ uint8_t reserved:2;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union payload_table_update_status {
-+ struct {
-+ uint8_t VC_PAYLOAD_TABLE_UPDATED:1;
-+ uint8_t ACT_HANDLED:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union device_irq_esi_0 {
-+ struct {
-+ uint8_t REMOTE_CONTROL_CMD_PENDING:1;
-+ uint8_t AUTOMATED_TEST_REQUEST:1;
-+ uint8_t CP_IRQ:1;
-+ uint8_t MCCS_IRQ:1;
-+ uint8_t DOWN_REP_MSG_RDY:1;
-+ uint8_t UP_REQ_MSG_RDY:1;
-+ uint8_t SINK_SPECIFIC_IRQ:1;
-+ uint8_t RESERVED:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union lane_status {
-+ struct {
-+ uint8_t CR_DONE_0:1;
-+ uint8_t CHANNEL_EQ_DONE_0:1;
-+ uint8_t SYMBOL_LOCKED_0:1;
-+ uint8_t RESERVED0:1;
-+ uint8_t CR_DONE_1:1;
-+ uint8_t CHANNEL_EQ_DONE_1:1;
-+ uint8_t SYMBOL_LOCKED_1:1;
-+ uint8_t RESERVED_1:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union device_service_irq {
-+ struct {
-+ uint8_t REMOTE_CONTROL_CMD_PENDING:1;
-+ uint8_t AUTOMATED_TEST:1;
-+ uint8_t CP_IRQ:1;
-+ uint8_t MCCS_IRQ:1;
-+ uint8_t DOWN_REP_MSG_RDY:1;
-+ uint8_t UP_REQ_MSG_RDY:1;
-+ uint8_t SINK_SPECIFIC:1;
-+ uint8_t reserved:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union downstream_port {
-+ struct {
-+ uint8_t PRESENT:1;
-+ uint8_t TYPE:2;
-+ uint8_t FORMAT_CONV:1;
-+ uint8_t DETAILED_CAPS:1;
-+ uint8_t RESERVED:3;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union sink_count {
-+ struct {
-+ uint8_t SINK_COUNT:6;
-+ uint8_t CPREADY:1;
-+ uint8_t RESERVED:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union lane_align_status_updated {
-+ struct {
-+ uint8_t INTERLANE_ALIGN_DONE:1;
-+ uint8_t POST_LT_ADJ_REQ_IN_PROGRESS:1;
-+ uint8_t RESERVED:4;
-+ uint8_t DOWNSTREAM_PORT_STATUS_CHANGED:1;
-+ uint8_t LINK_STATUS_UPDATED:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union lane_adjust {
-+ struct {
-+ uint8_t VOLTAGE_SWING_LANE:2;
-+ uint8_t PRE_EMPHASIS_LANE:2;
-+ uint8_t RESERVED:4;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+/* Automated test structures */
-+union test_request {
-+ struct {
-+ uint8_t LINK_TRAINING:1;
-+ uint8_t LINK_TEST_PATTERN:1;
-+ uint8_t EDID_READ:1;
-+ uint8_t PHY_TEST_PATTERN:1;
-+ uint8_t AUDIO_TEST_PATTERN:1;
-+ uint8_t AUDIO_TEST_NO_VIDEO:1;
-+ uint8_t RESERVED:1;
-+ uint8_t TEST_STEREO_3D:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union test_response {
-+ struct {
-+ uint8_t ACK:1;
-+ uint8_t NO_ACK:1;
-+ uint8_t RESERVED:6;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union link_test_pattern {
-+ struct {
-+ uint8_t PATTERN:2;/*DpcdLinkTestPatterns*/
-+ uint8_t RESERVED:6;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union test_misc {
-+ struct dpcd_test_misc_bits {
-+ uint8_t SYNC_CLOCK:1;
-+ uint8_t CLR_FORMAT:2;/*DpcdTestColorFormat*/
-+ uint8_t DYN_RANGE:1;/*DpcdTestDynRange*/
-+ uint8_t YCBCR:1;/*DpcdTestYCbCrStandard*/
-+ uint8_t BPC:3;/*DpcdTestBitDepth*/
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union phy_test_pattern {
-+ struct {
-+ /* This field is 2 bits for DP1.1 and 3 bits for DP1.2.*/
-+ uint8_t PATTERN:3;
-+ uint8_t RESERVED:5;/* BY spec, bit7:2 is 0 for DP1.1.*/
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union audio_test_mode {
-+ struct {
-+ uint8_t SAMPLING_RATE:4;
-+ uint8_t CHANNEL_COUNT:4;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union audio_tes_tpattern_period {
-+ struct {
-+ uint8_t PATTERN_PERIOD:4;
-+ uint8_t RESERVED:4;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+struct audio_test_pattern_type {
-+ uint8_t value;
-+};
-+
-+union dpcd_training_pattern {
-+ struct {
-+ uint8_t TRAINING_PATTERN_SET:2;
-+ uint8_t LINK_QUAL_PATTERN_SET:2;
-+ uint8_t RECOVERED_CLOCK_OUT_EN:1;
-+ uint8_t SCRAMBLING_DISABLE:1;
-+ uint8_t RESERVED:2;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+/* Training Lane is used to configure downstream DP device's voltage swing
-+and pre-emphasis levels*/
-+/* The DPCD addresses are from 0x103 to 0x106*/
-+union dpcd_training_lane {
-+ struct {
-+ uint8_t VOLTAGE_SWING_SET:2;
-+ uint8_t MAX_SWING_REACHED:1;
-+ uint8_t PRE_EMPHASIS_SET:2;
-+ uint8_t MAX_PRE_EMPHASIS_REACHED:1;
-+ uint8_t RESERVED:2;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+/*Training Lane Set 2 is used to configure downstream DP device's
-+post cursor 2 level of Training Pattern 2 or 3*/
-+/* The DPCD addresses are 0x10F (TRAINING_LANE0_1_SET2)
-+and 0x110 (TRAINING_LANE2_3_SET2)*/
-+union dpcd_training_lane_set2 {
-+ struct {
-+ uint8_t POST_CURSOR2_SET:2;
-+ uint8_t MAX_POST_CURSOR2_REACHED:1;
-+ uint8_t RESERVED:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union dpcd_psr_configuration {
-+ struct {
-+ uint8_t ENABLE:1;
-+ uint8_t TRANSMITTER_ACTIVE_IN_PSR:1;
-+ uint8_t CRC_VERIFICATION:1;
-+ uint8_t FRAME_CAPTURE_INDICATION:1;
-+ uint8_t LINE_CAPTURE_INDICATION:1;
-+ uint8_t IRQ_HPD_WITH_CRC_ERROR:1;
-+ uint8_t RESERVED:2;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union psr_error_status {
-+ struct {
-+ uint8_t LINK_CRC_ERROR:1;
-+ uint8_t RFB_STORAGE_ERROR:1;
-+ uint8_t RESERVED:6;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union psr_event_status_ind {
-+ struct {
-+ uint8_t SINK_PSR_CAP_CHANGE:1;
-+ uint8_t RESERVED:7;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union psr_sink_psr_status {
-+ struct {
-+ uint8_t SINK_SELF_REFRESH_STATUS:3;
-+ uint8_t RESERVED:5;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+/* EDP related 0x701 */
-+union edp_generial_cap1 {
-+ struct {
-+ uint8_t TCON_BACKLIGHT_ADJUSTMENT_CAPABLE:1;
-+ uint8_t BACKLIGHT_PIN_ENABLE_CAPABLE:1;
-+ uint8_t BACKLIGHT_AUX_ENABLE_CAPABLE:1;
-+ uint8_t PANEL_SELFTEST_PIN_ENABLE_CAPABLE:1;
-+ uint8_t BACKLIGHT_SELFTEST_AUX_ENABLE_CAPABLE:1;
-+ uint8_t FRC_ENABLE_CAPABLE:1;
-+ uint8_t COLOR_ENGINE_CAPABLE:1;
-+ /*bit 7, pane can be controlled by 0x600*/
-+ uint8_t SET_POWER_CAPABLE:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+/* TMDS-converter related */
-+union dwnstream_port_caps_byte0 {
-+ struct {
-+ uint8_t DWN_STRM_PORTX_TYPE:3;
-+ uint8_t DWN_STRM_PORTX_HPD:1;
-+ uint8_t RESERVERD:4;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+/* these are the detailed types stored at DWN_STRM_PORTX_CAP (00080h)*/
-+enum dpcd_downstream_port_detailed_type {
-+ DOWN_STREAM_DETAILED_DP = 0,
-+ DOWN_STREAM_DETAILED_VGA,
-+ DOWN_STREAM_DETAILED_DVI,
-+ DOWN_STREAM_DETAILED_HDMI,
-+ DOWN_STREAM_DETAILED_NONDDC,/* has no EDID (TV,CV)*/
-+ DOWN_STREAM_DETAILED_DP_PLUS_PLUS
-+};
-+
-+union dwnstream_port_caps_byte2 {
-+ struct {
-+ uint8_t MAX_BITS_PER_COLOR_COMPONENT:2;
-+ uint8_t RESERVED:6;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union dp_downstream_port_present {
-+ uint8_t byte;
-+ struct {
-+ uint8_t PORT_PRESENT:1;
-+ uint8_t PORT_TYPE:2;
-+ uint8_t FMT_CONVERSION:1;
-+ uint8_t DETAILED_CAPS:1;
-+ uint8_t RESERVED:3;
-+ } fields;
-+};
-+
-+
-+union dwnstream_port_caps_byte3_dvi {
-+ struct {
-+ uint8_t RESERVED1:1;
-+ uint8_t DUAL_LINK:1;
-+ uint8_t HIGH_COLOR_DEPTH:1;
-+ uint8_t RESERVED2:5;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union dwnstream_port_caps_byte3_hdmi {
-+ struct {
-+ uint8_t FRAME_SEQ_TO_FRAME_PACK:1;
-+ uint8_t RESERVED:7;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+/*4-byte structure for detailed capabilities of a down-stream port
-+(DP-to-TMDS converter).*/
-+union dwnstream_portx_caps {
-+ struct {
-+ union dwnstream_port_caps_byte0 byte0;
-+ uint8_t max_tmds_clk;/* byte1 */
-+ union dwnstream_port_caps_byte2 byte2;
-+
-+ union {
-+ union dwnstream_port_caps_byte3_dvi byte_dvi;
-+ union dwnstream_port_caps_byte3_hdmi byte_hdmi;
-+ } byte3;
-+ } bytes;
-+ uint8_t raw[4];
-+};
-+
-+union sink_status {
-+ struct {
-+ uint8_t RX_PORT0_STATUS:1;
-+ uint8_t RX_PORT1_STATUS:1;
-+ uint8_t RESERVED:6;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+/*6-byte structure corresponding to 6 registers (200h-205h)
-+read during handling of HPD-IRQ*/
-+union hpd_irq_data {
-+ struct {
-+ union sink_count sink_cnt;/* 200h */
-+ union device_service_irq device_service_irq;/* 201h */
-+ union lane_status lane01_status;/* 202h */
-+ union lane_status lane23_status;/* 203h */
-+ union lane_align_status_updated lane_status_updated;/* 204h */
-+ union sink_status sink_status;
-+ } bytes;
-+ uint8_t raw[6];
-+};
-+
-+union down_stream_port_count {
-+ struct {
-+ uint8_t DOWN_STR_PORT_COUNT:4;
-+ uint8_t RESERVED:2; /*Bits 5:4 = RESERVED. Read all 0s.*/
-+ /*Bit 6 = MSA_TIMING_PAR_IGNORED
-+ 0 = Sink device requires the MSA timing parameters
-+ 1 = Sink device is capable of rendering incoming video
-+ stream without MSA timing parameters*/
-+ uint8_t IGNORE_MSA_TIMING_PARAM:1;
-+ /*Bit 7 = OUI Support
-+ 0 = OUI not supported
-+ 1 = OUI supported
-+ (OUI and Device Identification mandatory for DP 1.2)*/
-+ uint8_t OUI_SUPPORT:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union down_spread_ctrl {
-+ struct {
-+ uint8_t RESERVED1:4;/* Bit 3:0 = RESERVED. Read all 0s*/
-+ /* Bits 4 = SPREAD_AMP. Spreading amplitude
-+ 0 = Main link signal is not downspread
-+ 1 = Main link signal is downspread <= 0.5%
-+ with frequency in the range of 30kHz ~ 33kHz*/
-+ uint8_t SPREAD_AMP:1;
-+ uint8_t RESERVED2:2;/*Bit 6:5 = RESERVED. Read all 0s*/
-+ /*Bit 7 = MSA_TIMING_PAR_IGNORE_EN
-+ 0 = Source device will send valid data for the MSA Timing Params
-+ 1 = Source device may send invalid data for these MSA Timing Params*/
-+ uint8_t IGNORE_MSA_TIMING_PARAM:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union dpcd_edp_config {
-+ struct {
-+ uint8_t PANEL_MODE_EDP:1;
-+ uint8_t FRAMING_CHANGE_ENABLE:1;
-+ uint8_t RESERVED:5;
-+ uint8_t PANEL_SELF_TEST_ENABLE:1;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+struct dp_device_vendor_id {
-+ uint8_t ieee_oui[3];/*24-bit IEEE OUI*/
-+ uint8_t ieee_device_id[6];/*usually 6-byte ASCII name*/
-+};
-+
-+struct dp_sink_hw_fw_revision {
-+ uint8_t ieee_hw_rev;
-+ uint8_t ieee_fw_rev[2];
-+};
-+
-+/*DPCD register of DP receiver capability field bits-*/
-+union edp_configuration_cap {
-+ struct {
-+ uint8_t ALT_SCRAMBLER_RESET:1;
-+ uint8_t FRAMING_CHANGE:1;
-+ uint8_t RESERVED:1;
-+ uint8_t DPCD_DISPLAY_CONTROL_CAPABLE:1;
-+ uint8_t RESERVED2:4;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+union psr_capabilities {
-+ struct {
-+ uint8_t EXIT_LT_NOT_REQ:1;
-+ uint8_t RFB_SETUP_TIME:3;
-+ uint8_t RESERVED:4;
-+ } bits;
-+ uint8_t raw;
-+};
-+
-+#endif /* __DAL_DPCD_DEFS_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/dvo_interface.h b/drivers/gpu/drm/amd/dal/include/dvo_interface.h
-new file mode 100644
-index 0000000..58d2c6f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/dvo_interface.h
-@@ -0,0 +1,48 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DVO_INTERFACE_H__
-+#define __DAL_DVO_INTERFACE_H__
-+
-+#include "gpio_types.h"
-+
-+struct dvo;
-+
-+enum gpio_result dal_dvo_open(
-+ struct dvo *dvo,
-+ enum gpio_mode mode);
-+
-+enum gpio_result dal_dvo_get_value(
-+ const struct dvo *dvo,
-+ uint32_t *value);
-+
-+enum gpio_result dal_dvo_set_value(
-+ const struct dvo *dvo,
-+ uint32_t value);
-+
-+void dal_dvo_close(
-+ struct dvo *dvo);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/encoder_interface.h b/drivers/gpu/drm/amd/dal/include/encoder_interface.h
-new file mode 100644
-index 0000000..5fbf816
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/encoder_interface.h
-@@ -0,0 +1,278 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of enc software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and enc permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_ENCODER_INTERFACE_H__
-+#define __DAL_ENCODER_INTERFACE_H__
-+
-+#include "encoder_types.h"
-+#include "adapter_service_interface.h"
-+#include "fixed31_32.h"
-+
-+enum encoder_result {
-+ ENCODER_RESULT_OK,
-+ ENCODER_RESULT_ERROR,
-+ ENCODER_RESULT_NOBANDWIDTH,
-+ ENCODER_RESULT_SINKCONNECTIVITYCHANGED,
-+};
-+
-+struct encoder_init_data {
-+ struct adapter_service *adapter_service;
-+ enum channel_id channel;
-+ struct graphics_object_id connector;
-+ enum hpd_source_id hpd_source;
-+ /* TODO: in DAL2, here was pointer to EventManagerInterface */
-+ struct graphics_object_id encoder;
-+ struct dc_context *ctx;
-+};
-+
-+/* forward declaration */
-+struct encoder;
-+
-+struct encoder *dal_encoder_create(
-+ const struct encoder_init_data *init_data);
-+
-+/* access graphics object base */
-+const struct graphics_object_id dal_encoder_get_graphics_object_id(
-+ const struct encoder *enc);
-+
-+/*
-+ * Signal types support
-+ */
-+uint32_t dal_encoder_enumerate_input_signals(
-+ const struct encoder *enc);
-+uint32_t dal_encoder_enumerate_output_signals(
-+ const struct encoder *enc);
-+bool dal_encoder_is_input_signal_supported(
-+ const struct encoder *enc,
-+ enum signal_type signal);
-+bool dal_encoder_is_output_signal_supported(
-+ const struct encoder *enc,
-+ enum signal_type signal);
-+void dal_encoder_set_input_signals(
-+ struct encoder *enc,
-+ uint32_t signals);
-+void dal_encoder_set_output_signals(
-+ struct encoder *enc,
-+ uint32_t signals);
-+
-+/*
-+ * Programming interface
-+ */
-+/* perform power-up sequence (boot up, resume, recovery) */
-+enum encoder_result dal_encoder_power_up(
-+ struct encoder *enc,
-+ const struct encoder_context *ctx);
-+/* perform power-down (shut down, stand-by */
-+enum encoder_result dal_encoder_power_down(
-+ struct encoder *enc,
-+ const struct encoder_output *output);
-+/* setup encoder block (DIG, DVO, DAC), does not enables encoder */
-+enum encoder_result dal_encoder_setup(
-+ struct encoder *enc,
-+ const struct encoder_output *output);
-+/* activate transmitter,
-+ * do preparation before enables the actual stream output */
-+enum encoder_result dal_encoder_pre_enable_output(
-+ struct encoder *enc,
-+ const struct encoder_pre_enable_output_param *param);
-+/* activate transmitter, enables actual stream output */
-+enum encoder_result dal_encoder_enable_output(
-+ struct encoder *enc,
-+ const struct encoder_output *output);
-+/* deactivate transmitter, disables stream output */
-+enum encoder_result dal_encoder_disable_output(
-+ struct encoder *enc,
-+ const struct encoder_output *output);
-+/* output blank data,
-+ *prevents output of the actual surface data on active transmitter */
-+enum encoder_result dal_encoder_blank(
-+ struct encoder *enc,
-+ const struct encoder_context *ctx);
-+/* stop sending blank data,
-+ * output the actual surface data on active transmitter */
-+enum encoder_result dal_encoder_unblank(
-+ struct encoder *enc,
-+ const struct encoder_unblank_param *param);
-+/* setup stereo signal from given controller */
-+enum encoder_result dal_encoder_setup_stereo(
-+ struct encoder *enc,
-+ const struct encoder_3d_setup *setup);
-+/* enable HSync/VSync output from given controller */
-+enum encoder_result dal_encoder_enable_sync_output(
-+ struct encoder *enc,
-+ enum sync_source src);
-+/* disable HSync/VSync output */
-+enum encoder_result dal_encoder_disable_sync_output(
-+ struct encoder *enc);
-+/* action of encoder before DDC transaction */
-+enum encoder_result dal_encoder_pre_ddc(
-+ struct encoder *enc,
-+ const struct encoder_context *ctx);
-+/* action of encoder after DDC transaction */
-+enum encoder_result dal_encoder_post_ddc(
-+ struct encoder *enc,
-+ const struct encoder_context *ctx);
-+/* CRT DDC EDID polling interrupt interface */
-+enum encoder_result dal_encoder_update_implementation(
-+ struct encoder *enc,
-+ const struct encoder_context *ctx);
-+/* set test pattern signal */
-+enum encoder_result dal_encoder_set_dp_phy_pattern(
-+ struct encoder *enc,
-+ const struct encoder_set_dp_phy_pattern_param *param);
-+
-+void dal_encoder_release_hw(struct encoder *enc);
-+/*
-+ * Information interface
-+ */
-+/* check whether sink is present based on SENSE detection,
-+ * analog encoders will return true */
-+bool dal_encoder_is_sink_present(
-+ struct encoder *enc,
-+ struct graphics_object_id downstream);
-+/* detect load on the sink,
-+ * for analog signal,
-+ * load detection will be called for the specified signal */
-+enum signal_type dal_encoder_detect_load(
-+ struct encoder *enc,
-+ const struct encoder_context *ctx);
-+/* detect output sink type,
-+ * for digital perform sense detection,
-+ * for analog return encoder's signal type */
-+enum signal_type dal_encoder_detect_sink(
-+ struct encoder *enc,
-+ struct graphics_object_id downstream);
-+/* get transmitter id */
-+enum transmitter dal_encoder_get_transmitter(
-+ const struct encoder *enc);
-+/* */
-+enum transmitter dal_encoder_get_paired_transmitter(
-+ const struct encoder *enc);
-+/* */
-+enum physical_phy_id dal_encoder_get_phy(
-+ const struct encoder *enc);
-+/* */
-+enum physical_phy_id dal_encoder_get_paired_phy(
-+ const struct encoder *enc);
-+/* reports if the encoder supports given link settings */
-+bool dal_encoder_is_link_settings_supported(
-+ struct encoder *enc,
-+ const struct link_settings *link_settings);
-+/* options and features supported by encoder */
-+struct encoder_feature_support dal_encoder_get_supported_features(
-+ const struct encoder *enc);
-+/* reports list of supported stream engines */
-+union supported_stream_engines dal_encoder_get_supported_stream_engines(
-+ const struct encoder *enc);
-+/* reports preferred stream engine */
-+enum engine_id dal_encoder_get_preferred_stream_engine(
-+ const struct encoder *enc);
-+/* reports whether clock source can be used with enc encoder */
-+bool dal_encoder_is_clock_source_supported(
-+ const struct encoder *enc,
-+ enum clock_source_id clock_source);
-+/* check encoder capabilities to confirm
-+ * specified timing is in the encoder limits
-+ * when outputting certain signal */
-+enum encoder_result dal_encoder_validate_output(
-+ struct encoder *enc,
-+ const struct encoder_output *output);
-+/* retrieves sync source which outputs VSync signal from encoder */
-+enum sync_source dal_encoder_get_vsync_output_source(
-+ const struct encoder *enc);
-+/*
-+ * Adjustments
-+ */
-+/* update AVI info frame */
-+void dal_encoder_update_info_frame(
-+ struct encoder *enc,
-+ const struct encoder_info_frame_param *param);
-+/* */
-+void dal_encoder_stop_info_frame(
-+ struct encoder *enc,
-+ const struct encoder_context *ctx);
-+/* */
-+enum encoder_result dal_encoder_set_lcd_backlight_level(
-+ struct encoder *enc,
-+ uint32_t level);
-+/* backlight control interface */
-+enum encoder_result dal_encoder_backlight_control(
-+ struct encoder *enc,
-+ bool enable);
-+/*
-+ * DP MST programming
-+ */
-+/* update payload slot allocation for each DP MST stream */
-+enum encoder_result dal_encoder_update_mst_alloc_table(
-+ struct encoder *enc,
-+ const struct dp_mst_stream_allocation_table *table,
-+ bool is_removal);
-+/* enable virtual channel stream with throttled value X.Y */
-+enum encoder_result dal_encoder_enable_stream(
-+ struct encoder *enc,
-+ enum engine_id engine,
-+ struct fixed31_32 throttled_vcp_size);
-+/* disable virtual channel stream */
-+enum encoder_result dal_encoder_disable_stream(
-+ struct encoder *enc,
-+ enum engine_id engine);
-+void dal_encoder_set_multi_path(struct encoder *enc, bool is_multi_path);
-+/*
-+ * Test harness
-+ */
-+/* check whether Test Pattern enabled */
-+bool dal_encoder_is_test_pattern_enabled(
-+ struct encoder *enc,
-+ enum engine_id engine);
-+/* set lane parameters */
-+enum encoder_result dal_encoder_set_lane_settings(
-+ struct encoder *enc,
-+ const struct encoder_context *ctx,
-+ const struct link_training_settings *link_settings);
-+/* get lane parameters */
-+enum encoder_result dal_encoder_get_lane_settings(
-+ struct encoder *enc,
-+ const struct encoder_context *ctx,
-+ struct link_training_settings *link_settings);
-+/* enable master clock of HPD interrupt */
-+void dal_encoder_enable_hpd(
-+ struct encoder *enc,
-+ const struct encoder_context *ctx);
-+/* disable all HPD interrupts */
-+void dal_encoder_disable_hpd(
-+ struct encoder *enc,
-+ const struct encoder_context *ctx);
-+
-+/* get current HW state - used for optimization code path only */
-+enum clock_source_id dal_encoder_get_active_clock_source(
-+ const struct encoder *enc);
-+enum engine_id dal_encoder_get_active_engine(
-+ const struct encoder *enc);
-+
-+/* destroy encoder instance */
-+void dal_encoder_destroy(
-+ struct encoder **ptr);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/encoder_types.h b/drivers/gpu/drm/amd/dal/include/encoder_types.h
-new file mode 100644
-index 0000000..2897a1d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/encoder_types.h
-@@ -0,0 +1,216 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_ENCODER_TYPES_H__
-+#define __DAL_ENCODER_TYPES_H__
-+
-+#include "grph_object_defs.h"
-+#include "signal_types.h"
-+#include "hw_sequencer_types.h"
-+#include "link_service_types.h"
-+
-+struct encoder_context {
-+ /*
-+ * HW programming context
-+ */
-+ /* DIG id. Also used as AC context */
-+ enum engine_id engine;
-+ /* DDC line */
-+ enum channel_id channel;
-+ /* HPD line */
-+ enum hpd_source_id hpd_source;
-+ /*
-+ * ASIC Control (VBIOS) context
-+ */
-+ /* encoder output signal */
-+ enum signal_type signal;
-+ /* native connector id */
-+ struct graphics_object_id connector;
-+ /* downstream object (can be connector or downstream encoder) */
-+ struct graphics_object_id downstream;
-+};
-+
-+union encoder_flags {
-+ struct {
-+ /* enable audio (DP/eDP only) */
-+ uint32_t ENABLE_AUDIO:1;
-+ /* coherency */
-+ uint32_t COHERENT:1;
-+ /* delay after Pixel Format change before enable transmitter */
-+ uint32_t DELAY_AFTER_PIXEL_FORMAT_CHANGE:1;
-+ /* by default, do not turn off VCC when disabling output */
-+ uint32_t TURN_OFF_VCC:1;
-+ /* by default, do wait for HPD low after turn of panel VCC */
-+ uint32_t NO_WAIT_FOR_HPD_LOW:1;
-+ /* slow DP panels don't reset internal fifo */
-+ uint32_t VID_STREAM_DIFFER_TO_SYNC:1;
-+ } bits;
-+ uint32_t raw;
-+};
-+
-+struct encoder_info_packet {
-+ bool valid;
-+ uint8_t hb0;
-+ uint8_t hb1;
-+ uint8_t hb2;
-+ uint8_t hb3;
-+ uint8_t sb[28];
-+};
-+
-+struct encoder_info_frame {
-+ /* auxiliary video information */
-+ struct encoder_info_packet avi;
-+ struct encoder_info_packet gamut;
-+ struct encoder_info_packet vendor;
-+ /* source product description */
-+ struct encoder_info_packet spd;
-+ /* video stream configuration */
-+ struct encoder_info_packet vsc;
-+};
-+
-+struct encoder_info_frame_param {
-+ struct encoder_info_frame packets;
-+ struct encoder_context enc_ctx;
-+};
-+
-+/*TODO: cleanup pending encoder cleanup*/
-+struct encoder_output {
-+ /* encoder AC & HW programming context */
-+ struct encoder_context enc_ctx;
-+ /* requested timing */
-+ struct hw_crtc_timing crtc_timing;
-+ /* clock source id (PLL or external) */
-+ enum clock_source_id clock_source;
-+ /* link settings (DP/eDP only) */
-+ struct link_settings link_settings;
-+ /* info frame packets */
-+ struct encoder_info_frame info_frame;
-+ /* timing validation (HDMI only) */
-+ uint32_t max_tmds_clk_from_edid_in_mhz;
-+ /* edp panel mode */
-+ enum dp_panel_mode dp_panel_mode;
-+ /* delay in milliseconds after powering up DP receiver (DP/eDP only) */
-+ uint32_t delay_after_dp_receiver_power_up;
-+ /* various flags for features and workarounds */
-+ union encoder_flags flags;
-+ /* delay after pixel format change */
-+ uint32_t delay_after_pixel_format_change;
-+ /* controller id */
-+ enum controller_id controller;
-+ /* maximum supported deep color depth for HDMI */
-+ enum dc_color_depth max_hdmi_deep_color;
-+ /* maximum supported pixel clock for HDMI */
-+ uint32_t max_hdmi_pixel_clock;
-+};
-+
-+struct encoder_pre_enable_output_param {
-+ struct hw_crtc_timing crtc_timing;
-+ struct link_settings link_settings;
-+ struct encoder_context enc_ctx;
-+};
-+
-+struct encoder_unblank_param {
-+ struct hw_crtc_timing crtc_timing;
-+ struct link_settings link_settings;
-+ enum signal_type signal;
-+};
-+
-+/*
-+ * @brief
-+ * Parameters to setup stereo 3D mode in Encoder:
-+ * - source: used for side-band stereo sync (DVO/DAC);
-+ * - engine_id: defines engine for this Encoder;
-+ * - enable_inband: in-band stereo sync should be enabled;
-+ * - enable_sideband: side-band stereo sync should be enabled.
-+ */
-+struct encoder_3d_setup {
-+ enum engine_id engine;
-+ enum sync_source source;
-+ union {
-+ struct {
-+ uint32_t SETUP_SYNC_SOURCE:1;
-+ uint32_t ENABLE_INBAND:1;
-+ uint32_t ENABLE_SIDEBAND:1;
-+ uint32_t DISABLE_INBAND:1;
-+ uint32_t DISABLE_SIDEBAND:1;
-+ } bits;
-+ uint32_t raw;
-+ } flags;
-+};
-+
-+struct encoder_set_dp_phy_pattern_param {
-+ enum dp_test_pattern dp_phy_pattern;
-+ const uint8_t *custom_pattern;
-+ uint32_t custom_pattern_size;
-+ enum dp_panel_mode dp_panel_mode;
-+};
-+
-+struct encoder_feature_support {
-+ union {
-+ struct {
-+ /* 1 - external encoder; 0 - internal encoder */
-+ uint32_t EXTERNAL_ENCODER:1;
-+ uint32_t ANALOG_ENCODER:1;
-+ uint32_t STEREO_SYNC:1;
-+ /* check the DDC data pin
-+ * when performing DP Sink detection */
-+ uint32_t DP_SINK_DETECT_POLL_DATA_PIN:1;
-+ /* CPLIB authentication
-+ * for external DP chip supported */
-+ uint32_t CPLIB_DP_AUTHENTICATION:1;
-+ uint32_t IS_HBR2_CAPABLE:1;
-+ uint32_t IS_HBR2_VALIDATED:1;
-+ uint32_t IS_TPS3_CAPABLE:1;
-+ uint32_t IS_AUDIO_CAPABLE:1;
-+ uint32_t IS_VCE_SUPPORTED:1;
-+ uint32_t IS_CONVERTER:1;
-+ uint32_t IS_Y_ONLY_CAPABLE:1;
-+ uint32_t IS_YCBCR_CAPABLE:1;
-+ } bits;
-+ uint32_t raw;
-+ } flags;
-+ /* maximum supported deep color depth */
-+ enum dc_color_depth max_deep_color;
-+ /* maximum supported clock */
-+ uint32_t max_pixel_clock;
-+};
-+
-+enum dig_encoder_mode {
-+ DIG_ENCODER_MODE_DP,
-+ DIG_ENCODER_MODE_LVDS,
-+ DIG_ENCODER_MODE_DVI,
-+ DIG_ENCODER_MODE_HDMI,
-+ DIG_ENCODER_MODE_SDVO,
-+ DIG_ENCODER_MODE_DP_WITH_AUDIO,
-+ DIG_ENCODER_MODE_DP_MST,
-+
-+ /* direct HW translation ! */
-+ DIG_ENCODER_MODE_TV = 13,
-+ DIG_ENCODER_MODE_CV,
-+ DIG_ENCODER_MODE_CRT
-+};
-+
-+#endif
-+
-diff --git a/drivers/gpu/drm/amd/dal/include/fixed31_32.h b/drivers/gpu/drm/amd/dal/include/fixed31_32.h
-new file mode 100644
-index 0000000..507f9f6
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/fixed31_32.h
-@@ -0,0 +1,389 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_FIXED31_32_H__
-+#define __DAL_FIXED31_32_H__
-+
-+/*
-+ * @brief
-+ * Arithmetic operations on real numbers
-+ * represented as fixed-point numbers.
-+ * There are: 1 bit for sign,
-+ * 31 bit for integer part,
-+ * 32 bits for fractional part.
-+ *
-+ * @note
-+ * Currently, overflows and underflows are asserted;
-+ * no special result returned.
-+ */
-+
-+struct fixed31_32 {
-+ int64_t value;
-+};
-+
-+/*
-+ * @brief
-+ * Useful constants
-+ */
-+
-+static const struct fixed31_32 dal_fixed31_32_zero = { 0 };
-+static const struct fixed31_32 dal_fixed31_32_epsilon = { 1LL };
-+static const struct fixed31_32 dal_fixed31_32_half = { 0x80000000LL };
-+static const struct fixed31_32 dal_fixed31_32_one = { 0x100000000LL };
-+
-+static const struct fixed31_32 dal_fixed31_32_pi = { 13493037705LL };
-+static const struct fixed31_32 dal_fixed31_32_two_pi = { 26986075409LL };
-+static const struct fixed31_32 dal_fixed31_32_e = { 11674931555LL };
-+static const struct fixed31_32 dal_fixed31_32_ln2 = { 2977044471LL };
-+static const struct fixed31_32 dal_fixed31_32_ln2_div_2 = { 1488522236LL };
-+
-+/*
-+ * @brief
-+ * Initialization routines
-+ */
-+
-+/*
-+ * @brief
-+ * result = numerator / denominator
-+ */
-+struct fixed31_32 dal_fixed31_32_from_fraction(
-+ int64_t numerator,
-+ int64_t denominator);
-+
-+/*
-+ * @brief
-+ * result = arg
-+ */
-+struct fixed31_32 dal_fixed31_32_from_int(
-+ int64_t arg);
-+
-+/*
-+ * @brief
-+ * Unary operators
-+ */
-+
-+/*
-+ * @brief
-+ * result = -arg
-+ */
-+struct fixed31_32 dal_fixed31_32_neg(
-+ struct fixed31_32 arg);
-+
-+/*
-+ * @brief
-+ * result = abs(arg) := (arg >= 0) ? arg : -arg
-+ */
-+struct fixed31_32 dal_fixed31_32_abs(
-+ struct fixed31_32 arg);
-+
-+/*
-+ * @brief
-+ * Binary relational operators
-+ */
-+
-+/*
-+ * @brief
-+ * result = arg1 < arg2
-+ */
-+bool dal_fixed31_32_lt(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2);
-+
-+/*
-+ * @brief
-+ * result = arg1 <= arg2
-+ */
-+bool dal_fixed31_32_le(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2);
-+
-+/*
-+ * @brief
-+ * result = arg1 == arg2
-+ */
-+bool dal_fixed31_32_eq(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2);
-+
-+/*
-+ * @brief
-+ * result = min(arg1, arg2) := (arg1 <= arg2) ? arg1 : arg2
-+ */
-+struct fixed31_32 dal_fixed31_32_min(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2);
-+
-+/*
-+ * @brief
-+ * result = max(arg1, arg2) := (arg1 <= arg2) ? arg2 : arg1
-+ */
-+struct fixed31_32 dal_fixed31_32_max(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2);
-+
-+/*
-+ * @brief
-+ * | min_value, when arg <= min_value
-+ * result = | arg, when min_value < arg < max_value
-+ * | max_value, when arg >= max_value
-+ */
-+struct fixed31_32 dal_fixed31_32_clamp(
-+ struct fixed31_32 arg,
-+ struct fixed31_32 min_value,
-+ struct fixed31_32 max_value);
-+
-+/*
-+ * @brief
-+ * Binary shift operators
-+ */
-+
-+/*
-+ * @brief
-+ * result = arg << shift
-+ */
-+struct fixed31_32 dal_fixed31_32_shl(
-+ struct fixed31_32 arg,
-+ uint8_t shift);
-+
-+/*
-+ * @brief
-+ * result = arg >> shift
-+ */
-+struct fixed31_32 dal_fixed31_32_shr(
-+ struct fixed31_32 arg,
-+ uint8_t shift);
-+
-+/*
-+ * @brief
-+ * Binary additive operators
-+ */
-+
-+/*
-+ * @brief
-+ * result = arg1 + arg2
-+ */
-+struct fixed31_32 dal_fixed31_32_add(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2);
-+
-+/*
-+ * @brief
-+ * result = arg1 - arg2
-+ */
-+struct fixed31_32 dal_fixed31_32_sub_int(
-+ struct fixed31_32 arg1,
-+ int32_t arg2);
-+
-+/*
-+ * @brief
-+ * result = arg1 - arg2
-+ */
-+struct fixed31_32 dal_fixed31_32_sub(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2);
-+
-+/*
-+ * @brief
-+ * Binary multiplicative operators
-+ */
-+
-+/*
-+ * @brief
-+ * result = arg1 * arg2
-+ */
-+struct fixed31_32 dal_fixed31_32_mul_int(
-+ struct fixed31_32 arg1,
-+ int32_t arg2);
-+
-+/*
-+ * @brief
-+ * result = arg1 * arg2
-+ */
-+struct fixed31_32 dal_fixed31_32_mul(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2);
-+
-+/*
-+ * @brief
-+ * result = square(arg) := arg * arg
-+ */
-+struct fixed31_32 dal_fixed31_32_sqr(
-+ struct fixed31_32 arg);
-+
-+/*
-+ * @brief
-+ * result = arg1 / arg2
-+ */
-+struct fixed31_32 dal_fixed31_32_div_int(
-+ struct fixed31_32 arg1,
-+ int64_t arg2);
-+
-+/*
-+ * @brief
-+ * result = arg1 / arg2
-+ */
-+struct fixed31_32 dal_fixed31_32_div(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2);
-+
-+/*
-+ * @brief
-+ * Reciprocal function
-+ */
-+
-+/*
-+ * @brief
-+ * result = reciprocal(arg) := 1 / arg
-+ *
-+ * @note
-+ * No special actions taken in case argument is zero.
-+ */
-+struct fixed31_32 dal_fixed31_32_recip(
-+ struct fixed31_32 arg);
-+
-+/*
-+ * @brief
-+ * Trigonometric functions
-+ */
-+
-+/*
-+ * @brief
-+ * result = sinc(arg) := sin(arg) / arg
-+ *
-+ * @note
-+ * Argument specified in radians,
-+ * internally it's normalized to [-2pi...2pi] range.
-+ */
-+struct fixed31_32 dal_fixed31_32_sinc(
-+ struct fixed31_32 arg);
-+
-+/*
-+ * @brief
-+ * result = sin(arg)
-+ *
-+ * @note
-+ * Argument specified in radians,
-+ * internally it's normalized to [-2pi...2pi] range.
-+ */
-+struct fixed31_32 dal_fixed31_32_sin(
-+ struct fixed31_32 arg);
-+
-+/*
-+ * @brief
-+ * result = cos(arg)
-+ *
-+ * @note
-+ * Argument specified in radians
-+ * and should be in [-2pi...2pi] range -
-+ * passing arguments outside that range
-+ * will cause incorrect result!
-+ */
-+struct fixed31_32 dal_fixed31_32_cos(
-+ struct fixed31_32 arg);
-+
-+/*
-+ * @brief
-+ * Transcendent functions
-+ */
-+
-+/*
-+ * @brief
-+ * result = exp(arg)
-+ *
-+ * @note
-+ * Currently, function is verified for abs(arg) <= 1.
-+ */
-+struct fixed31_32 dal_fixed31_32_exp(
-+ struct fixed31_32 arg);
-+
-+/*
-+ * @brief
-+ * result = log(arg)
-+ *
-+ * @note
-+ * Currently, abs(arg) should be less than 1.
-+ * No normalization is done.
-+ * Currently, no special actions taken
-+ * in case of invalid argument(s). Take care!
-+ */
-+struct fixed31_32 dal_fixed31_32_log(
-+ struct fixed31_32 arg);
-+
-+/*
-+ * @brief
-+ * Power function
-+ */
-+
-+/*
-+ * @brief
-+ * result = pow(arg1, arg2)
-+ *
-+ * @note
-+ * Currently, abs(arg1) should be less than 1. Take care!
-+ */
-+struct fixed31_32 dal_fixed31_32_pow(
-+ struct fixed31_32 arg1,
-+ struct fixed31_32 arg2);
-+
-+/*
-+ * @brief
-+ * Rounding functions
-+ */
-+
-+/*
-+ * @brief
-+ * result = floor(arg) := greatest integer lower than or equal to arg
-+ */
-+int32_t dal_fixed31_32_floor(
-+ struct fixed31_32 arg);
-+
-+/*
-+ * @brief
-+ * result = round(arg) := integer nearest to arg
-+ */
-+int32_t dal_fixed31_32_round(
-+ struct fixed31_32 arg);
-+
-+/*
-+ * @brief
-+ * result = ceil(arg) := lowest integer greater than or equal to arg
-+ */
-+int32_t dal_fixed31_32_ceil(
-+ struct fixed31_32 arg);
-+
-+/* the following two function are used in scaler hw programming to convert fixed
-+ * point value to format 2 bits from integer part and 19 bits from fractional
-+ * part. The same applies for u0d19, 0 bits from integer part and 19 bits from
-+ * fractional
-+ */
-+
-+uint32_t dal_fixed31_32_u2d19(
-+ struct fixed31_32 arg);
-+
-+uint32_t dal_fixed31_32_u0d19(
-+ struct fixed31_32 arg);
-+
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/fixed32_32.h b/drivers/gpu/drm/amd/dal/include/fixed32_32.h
-new file mode 100644
-index 0000000..5fca957
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/fixed32_32.h
-@@ -0,0 +1,80 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_FIXED32_32_H__
-+#define __DAL_FIXED32_32_H__
-+
-+struct fixed32_32 {
-+ uint64_t value;
-+};
-+
-+static const struct fixed32_32 dal_fixed32_32_zero = { 0 };
-+static const struct fixed32_32 dal_fixed32_32_one = { 0x100000000LL };
-+static const struct fixed32_32 dal_fixed32_32_half = { 0x80000000LL };
-+
-+struct fixed32_32 dal_fixed32_32_from_fraction(uint32_t n, uint32_t d);
-+struct fixed32_32 dal_fixed32_32_from_int(uint32_t value);
-+struct fixed32_32 dal_fixed32_32_add(
-+ struct fixed32_32 lhs,
-+ struct fixed32_32 rhs);
-+struct fixed32_32 dal_fixed32_32_add_int(
-+ struct fixed32_32 lhs,
-+ uint32_t rhs);
-+struct fixed32_32 dal_fixed32_32_sub(
-+ struct fixed32_32 lhs,
-+ struct fixed32_32 rhs);
-+struct fixed32_32 dal_fixed32_32_sub_int(
-+ struct fixed32_32 lhs,
-+ uint32_t rhs);
-+struct fixed32_32 dal_fixed32_32_mul(
-+ struct fixed32_32 lhs,
-+ struct fixed32_32 rhs);
-+struct fixed32_32 dal_fixed32_32_mul_int(
-+ struct fixed32_32 lhs,
-+ uint32_t rhs);
-+struct fixed32_32 dal_fixed32_32_div(
-+ struct fixed32_32 lhs,
-+ struct fixed32_32 rhs);
-+struct fixed32_32 dal_fixed32_32_div_int(
-+ struct fixed32_32 lhs,
-+ uint32_t rhs);
-+struct fixed32_32 dal_fixed32_32_min(
-+ struct fixed32_32 lhs,
-+ struct fixed32_32 rhs);
-+struct fixed32_32 dal_fixed32_32_max(
-+ struct fixed32_32 lhs,
-+ struct fixed32_32 rhs);
-+bool dal_fixed32_32_gt(struct fixed32_32 lhs, struct fixed32_32 rhs);
-+bool dal_fixed32_32_gt_int(struct fixed32_32 lhs, uint32_t rhs);
-+bool dal_fixed32_32_lt(struct fixed32_32 lhs, struct fixed32_32 rhs);
-+bool dal_fixed32_32_lt_int(struct fixed32_32 lhs, uint32_t rhs);
-+bool dal_fixed32_32_le(struct fixed32_32 lhs, struct fixed32_32 rhs);
-+bool dal_fixed32_32_le_int(struct fixed32_32 lhs, uint32_t rhs);
-+bool dal_fixed32_32_eq(struct fixed32_32 lhs, struct fixed32_32 rhs);
-+uint32_t dal_fixed32_32_ceil(struct fixed32_32 value);
-+uint32_t dal_fixed32_32_floor(struct fixed32_32 value);
-+uint32_t dal_fixed32_32_round(struct fixed32_32 value);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/gpio_interface.h b/drivers/gpu/drm/amd/dal/include/gpio_interface.h
-new file mode 100644
-index 0000000..a084d79
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/gpio_interface.h
-@@ -0,0 +1,93 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_GPIO_INTERFACE_H__
-+#define __DAL_GPIO_INTERFACE_H__
-+
-+#include "gpio_types.h"
-+#include "grph_object_defs.h"
-+
-+struct gpio;
-+
-+/* Open the handle for future use */
-+enum gpio_result dal_gpio_open(
-+ struct gpio *gpio,
-+ enum gpio_mode mode);
-+
-+enum gpio_result dal_gpio_open_ex(
-+ struct gpio *gpio,
-+ enum gpio_mode mode,
-+ void *options);
-+
-+/* Get high or low from the pin */
-+enum gpio_result dal_gpio_get_value(
-+ const struct gpio *gpio,
-+ uint32_t *value);
-+
-+/* Set pin high or low */
-+enum gpio_result dal_gpio_set_value(
-+ const struct gpio *gpio,
-+ uint32_t value);
-+
-+/* Get current mode */
-+enum gpio_mode dal_gpio_get_mode(
-+ const struct gpio *gpio);
-+
-+/* Change mode of the handle */
-+enum gpio_result dal_gpio_change_mode(
-+ struct gpio *gpio,
-+ enum gpio_mode mode);
-+
-+/* Get the GPIO id */
-+enum gpio_id dal_gpio_get_id(
-+ const struct gpio *gpio);
-+
-+/* Get the GPIO enum */
-+uint32_t dal_gpio_get_enum(
-+ const struct gpio *gpio);
-+
-+/* Set the GPIO pin configuration */
-+enum gpio_result dal_gpio_set_config(
-+ struct gpio *gpio,
-+ const struct gpio_config_data *config_data);
-+
-+/* Obtain GPIO pin info */
-+enum gpio_result dal_gpio_get_pin_info(
-+ const struct gpio *gpio,
-+ struct gpio_pin_info *pin_info);
-+
-+/* Obtain GPIO sync source */
-+enum sync_source dal_gpio_get_sync_source(
-+ const struct gpio *gpio);
-+
-+/* Obtain GPIO pin output state (active low or active high) */
-+enum gpio_pin_output_state dal_gpio_get_output_state(
-+ const struct gpio *gpio);
-+
-+/* Close the handle */
-+void dal_gpio_close(
-+ struct gpio *gpio);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/gpio_service_interface.h b/drivers/gpu/drm/amd/dal/include/gpio_service_interface.h
-new file mode 100644
-index 0000000..b22bb1b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/gpio_service_interface.h
-@@ -0,0 +1,94 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_GPIO_SERVICE_INTERFACE_H__
-+#define __DAL_GPIO_SERVICE_INTERFACE_H__
-+
-+#include "gpio_types.h"
-+#include "gpio_interface.h"
-+#include "dvo_interface.h"
-+#include "ddc_interface.h"
-+#include "irq_interface.h"
-+
-+struct gpio_service;
-+
-+struct gpio_service *dal_gpio_service_create(
-+ enum dce_version dce_version,
-+ struct dc_context *ctx);
-+
-+struct gpio *dal_gpio_service_create_gpio(
-+ struct gpio_service *service,
-+ uint32_t offset,
-+ uint32_t mask,
-+ enum gpio_pin_output_state output_state);
-+
-+struct gpio *dal_gpio_service_create_gpio_ex(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en,
-+ enum gpio_pin_output_state output_state);
-+
-+void dal_gpio_service_destroy_gpio(
-+ struct gpio **gpio);
-+
-+struct ddc *dal_gpio_service_create_ddc(
-+ struct gpio_service *service,
-+ uint32_t offset,
-+ uint32_t mask,
-+ struct gpio_ddc_hw_info *info);
-+
-+void dal_gpio_service_destroy_ddc(
-+ struct ddc **ddc);
-+
-+struct dvo *dal_gpio_service_create_dvo(
-+ struct gpio_service *service,
-+ uint32_t offset,
-+ uint32_t mask);
-+
-+struct dvo *dal_gpio_service_create_dvo_ex(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en);
-+
-+void dal_gpio_service_destroy_dvo(
-+ struct dvo **ptr);
-+
-+struct irq *dal_gpio_service_create_irq(
-+ struct gpio_service *service,
-+ uint32_t offset,
-+ uint32_t mask);
-+
-+struct irq *dal_gpio_service_create_irq_ex(
-+ struct gpio_service *service,
-+ enum gpio_id id,
-+ uint32_t en);
-+
-+void dal_gpio_service_destroy_irq(
-+ struct irq **ptr);
-+
-+void dal_gpio_service_destroy(
-+ struct gpio_service **ptr);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/gpio_types.h b/drivers/gpu/drm/amd/dal/include/gpio_types.h
-new file mode 100644
-index 0000000..d616d62
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/gpio_types.h
-@@ -0,0 +1,393 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_GPIO_TYPES_H__
-+#define __DAL_GPIO_TYPES_H__
-+
-+#define BUNDLE_A_MASK 0x00FFF000L
-+#define BUNDLE_B_MASK 0x00000FFFL
-+
-+/*
-+ * gpio_result
-+ *
-+ * @brief
-+ * The possible return codes that the GPIO object can return.
-+ * These return codes can be generated
-+ * directly by the GPIO object or from the GPIOPin object.
-+ */
-+enum gpio_result {
-+ GPIO_RESULT_OK,
-+ GPIO_RESULT_NULL_HANDLE,
-+ GPIO_RESULT_INVALID_DATA,
-+ GPIO_RESULT_DEVICE_BUSY,
-+ GPIO_RESULT_OPEN_FAILED,
-+ GPIO_RESULT_ALREADY_OPENED,
-+ GPIO_RESULT_NON_SPECIFIC_ERROR
-+};
-+
-+/*
-+ * @brief
-+ * Used to identify the specific GPIO device
-+ *
-+ * @notes
-+ * These constants are used as indices in a vector.
-+ * Thus they should start from zero and be contiguous.
-+ */
-+enum gpio_id {
-+ GPIO_ID_UNKNOWN = (-1),
-+ GPIO_ID_DVO1,
-+ GPIO_ID_DVO12,
-+ GPIO_ID_DVO24,
-+ GPIO_ID_DDC_DATA,
-+ GPIO_ID_DDC_CLOCK,
-+ GPIO_ID_GENERIC,
-+ GPIO_ID_HPD,
-+ GPIO_ID_GPIO_PAD,
-+ GPIO_ID_VIP_PAD,
-+ GPIO_ID_SYNC,
-+ GPIO_ID_GSL, /* global swap lock */
-+ GPIO_ID_COUNT,
-+ GPIO_ID_MIN = GPIO_ID_DVO1,
-+ GPIO_ID_MAX = GPIO_ID_GSL
-+};
-+
-+#define GPIO_ENUM_UNKNOWN \
-+ 32
-+
-+struct gpio_pin_info {
-+ uint32_t offset;
-+ uint32_t offset_y;
-+ uint32_t offset_en;
-+ uint32_t offset_mask;
-+
-+ uint32_t mask;
-+ uint32_t mask_y;
-+ uint32_t mask_en;
-+ uint32_t mask_mask;
-+};
-+
-+enum gpio_pin_output_state {
-+ GPIO_PIN_OUTPUT_STATE_ACTIVE_LOW,
-+ GPIO_PIN_OUTPUT_STATE_ACTIVE_HIGH,
-+ GPIO_PIN_OUTPUT_STATE_DEFAULT = GPIO_PIN_OUTPUT_STATE_ACTIVE_LOW
-+};
-+
-+enum gpio_dvo1 {
-+ GPIO_DVO1_UNKNOWN = (-1),
-+ GPIO_DVO1_0,
-+ GPIO_DVO1_1,
-+ GPIO_DVO1_2,
-+ GPIO_DVO1_3,
-+ GPIO_DVO1_4,
-+ GPIO_DVO1_5,
-+ GPIO_DVO1_6,
-+ GPIO_DVO1_7,
-+ GPIO_DVO1_8,
-+ GPIO_DVO1_9,
-+ GPIO_DVO1_10,
-+ GPIO_DVO1_11,
-+ GPIO_DVO1_12,
-+ GPIO_DVO1_13,
-+ GPIO_DVO1_14,
-+ GPIO_DVO1_15,
-+ GPIO_DVO1_16,
-+ GPIO_DVO1_17,
-+ GPIO_DVO1_18,
-+ GPIO_DVO1_19,
-+ GPIO_DVO1_20,
-+ GPIO_DVO1_21,
-+ GPIO_DVO1_22,
-+ GPIO_DVO1_23,
-+ GPIO_DVO1_COUNT,
-+ GPIO_DVO1_MIN = GPIO_DVO1_0,
-+ GPIO_DVO1_MAX = GPIO_DVO1_23
-+};
-+
-+enum gpio_dvo12 {
-+ GPIO_DVO12_UNKNOWN = (-1),
-+ GPIO_DVO12_A,
-+ GPIO_DVO12_B,
-+ GPIO_DVO12_COUNT,
-+ GPIO_DVO12_MIN = GPIO_DVO12_A,
-+ GPIO_DVO12_MAX = GPIO_DVO12_B
-+};
-+
-+enum gpio_dvo24 {
-+ GPIO_DVO24_UNKNOWN = (-1),
-+ GPIO_DVO24_A,
-+ GPIO_DVO24_COUNT,
-+ GPIO_DVO24_MIN = GPIO_DVO24_A,
-+ GPIO_DVO24_MAX = GPIO_DVO24_A
-+};
-+
-+enum gpio_generic {
-+ GPIO_GENERIC_UNKNOWN = (-1),
-+ GPIO_GENERIC_A,
-+ GPIO_GENERIC_B,
-+ GPIO_GENERIC_C,
-+ GPIO_GENERIC_D,
-+ GPIO_GENERIC_E,
-+ GPIO_GENERIC_F,
-+ GPIO_GENERIC_G,
-+ GPIO_GENERIC_COUNT,
-+ GPIO_GENERIC_MIN = GPIO_GENERIC_A,
-+ GPIO_GENERIC_MAX = GPIO_GENERIC_B
-+};
-+
-+enum gpio_hpd {
-+ GPIO_HPD_UNKNOWN = (-1),
-+ GPIO_HPD_1,
-+ GPIO_HPD_2,
-+ GPIO_HPD_3,
-+ GPIO_HPD_4,
-+ GPIO_HPD_5,
-+ GPIO_HPD_6,
-+ GPIO_HPD_COUNT,
-+ GPIO_HPD_MIN = GPIO_HPD_1,
-+ GPIO_HPD_MAX = GPIO_HPD_6
-+};
-+
-+enum gpio_gpio_pad {
-+ GPIO_GPIO_PAD_UNKNOWN = (-1),
-+ GPIO_GPIO_PAD_0,
-+ GPIO_GPIO_PAD_1,
-+ GPIO_GPIO_PAD_2,
-+ GPIO_GPIO_PAD_3,
-+ GPIO_GPIO_PAD_4,
-+ GPIO_GPIO_PAD_5,
-+ GPIO_GPIO_PAD_6,
-+ GPIO_GPIO_PAD_7,
-+ GPIO_GPIO_PAD_8,
-+ GPIO_GPIO_PAD_9,
-+ GPIO_GPIO_PAD_10,
-+ GPIO_GPIO_PAD_11,
-+ GPIO_GPIO_PAD_12,
-+ GPIO_GPIO_PAD_13,
-+ GPIO_GPIO_PAD_14,
-+ GPIO_GPIO_PAD_15,
-+ GPIO_GPIO_PAD_16,
-+ GPIO_GPIO_PAD_17,
-+ GPIO_GPIO_PAD_18,
-+ GPIO_GPIO_PAD_19,
-+ GPIO_GPIO_PAD_20,
-+ GPIO_GPIO_PAD_21,
-+ GPIO_GPIO_PAD_22,
-+ GPIO_GPIO_PAD_23,
-+ GPIO_GPIO_PAD_24,
-+ GPIO_GPIO_PAD_25,
-+ GPIO_GPIO_PAD_26,
-+ GPIO_GPIO_PAD_27,
-+ GPIO_GPIO_PAD_28,
-+ GPIO_GPIO_PAD_29,
-+ GPIO_GPIO_PAD_30,
-+ GPIO_GPIO_PAD_COUNT,
-+ GPIO_GPIO_PAD_MIN = GPIO_GPIO_PAD_0,
-+ GPIO_GPIO_PAD_MAX = GPIO_GPIO_PAD_30
-+};
-+
-+enum gpio_vip_pad {
-+ GPIO_VIP_PAD_UNKNOWN = (-1),
-+ /* following never used -
-+ * GPIO_ID_DDC_CLOCK::GPIO_DDC_LINE_VIP_PAD defined instead */
-+ GPIO_VIP_PAD_SCL,
-+ /* following never used -
-+ * GPIO_ID_DDC_DATA::GPIO_DDC_LINE_VIP_PAD defined instead */
-+ GPIO_VIP_PAD_SDA,
-+ GPIO_VIP_PAD_VHAD,
-+ GPIO_VIP_PAD_VPHCTL,
-+ GPIO_VIP_PAD_VIPCLK,
-+ GPIO_VIP_PAD_VID,
-+ GPIO_VIP_PAD_VPCLK0,
-+ GPIO_VIP_PAD_DVALID,
-+ GPIO_VIP_PAD_PSYNC,
-+ GPIO_VIP_PAD_COUNT,
-+ GPIO_VIP_PAD_MIN = GPIO_VIP_PAD_SCL,
-+ GPIO_VIP_PAD_MAX = GPIO_VIP_PAD_PSYNC
-+};
-+
-+enum gpio_sync {
-+ GPIO_SYNC_UNKNOWN = (-1),
-+ GPIO_SYNC_HSYNC_A,
-+ GPIO_SYNC_VSYNC_A,
-+ GPIO_SYNC_HSYNC_B,
-+ GPIO_SYNC_VSYNC_B,
-+ GPIO_SYNC_COUNT,
-+ GPIO_SYNC_MIN = GPIO_SYNC_HSYNC_A,
-+ GPIO_SYNC_MAX = GPIO_SYNC_VSYNC_B
-+};
-+
-+enum gpio_gsl {
-+ GPIO_GSL_UNKNOWN = (-1),
-+ GPIO_GSL_GENLOCK_CLOCK,
-+ GPIO_GSL_GENLOCK_VSYNC,
-+ GPIO_GSL_SWAPLOCK_A,
-+ GPIO_GSL_SWAPLOCK_B,
-+ GPIO_GSL_COUNT,
-+ GPIO_GSL_MIN = GPIO_GSL_GENLOCK_CLOCK,
-+ GPIO_GSL_MAX = GPIO_GSL_SWAPLOCK_B
-+};
-+
-+/*
-+ * @brief
-+ * Unique Id for DDC handle.
-+ * Values are meaningful (used as indexes to array)
-+ */
-+enum gpio_ddc_line {
-+ GPIO_DDC_LINE_UNKNOWN = (-1),
-+ GPIO_DDC_LINE_DDC1,
-+ GPIO_DDC_LINE_DDC2,
-+ GPIO_DDC_LINE_DDC3,
-+ GPIO_DDC_LINE_DDC4,
-+ GPIO_DDC_LINE_DDC5,
-+ GPIO_DDC_LINE_DDC6,
-+ GPIO_DDC_LINE_DDC_VGA,
-+ GPIO_DDC_LINE_VIP_PAD,
-+ GPIO_DDC_LINE_I2C_PAD = GPIO_DDC_LINE_VIP_PAD,
-+ GPIO_DDC_LINE_COUNT,
-+ GPIO_DDC_LINE_MIN = GPIO_DDC_LINE_DDC1,
-+ GPIO_DDC_LINE_MAX = GPIO_DDC_LINE_I2C_PAD
-+};
-+
-+/*
-+ * @brief
-+ * Identifies the mode of operation to open a GPIO device.
-+ * A GPIO device (pin) can be programmed in only one of these modes at a time.
-+ */
-+enum gpio_mode {
-+ GPIO_MODE_UNKNOWN = (-1),
-+ GPIO_MODE_INPUT,
-+ GPIO_MODE_OUTPUT,
-+ GPIO_MODE_FAST_OUTPUT,
-+ GPIO_MODE_HARDWARE,
-+ GPIO_MODE_INTERRUPT
-+};
-+
-+/*
-+ * @brief
-+ * Identifies the source of the signal when GPIO is in HW mode.
-+ * get_signal_source() will return GPIO_SYGNAL_SOURCE__UNKNOWN
-+ * when one of the following holds:
-+ * 1. GPIO is input GPIO
-+ * 2. GPIO is not opened in HW mode
-+ * 3. GPIO does not have fixed signal source
-+ * (like DC_GenericA have mux instead fixed)
-+ */
-+enum gpio_signal_source {
-+ GPIO_SIGNAL_SOURCE_UNKNOWN = (-1),
-+ GPIO_SIGNAL_SOURCE_DACA_STEREO_SYNC,
-+ GPIO_SIGNAL_SOURCE_PASS_THROUGH_STEREO_SYNC,
-+ GPIO_SIGNAL_SOURCE_DACB_STEREO_SYNC,
-+ GPIO_SIGNAL_SOURCE_DACA_HSYNC,
-+ GPIO_SIGNAL_SOURCE_DACB_HSYNC,
-+ GPIO_SIGNAL_SOURCE_DACA_VSYNC,
-+ GPIO_SIGNAL_SOURCE_DACB_VSYNC,
-+ GPIO_SIGNAL_SOURCE_DVO_STEREO_SYNC
-+};
-+
-+enum gpio_stereo_source {
-+ GPIO_STEREO_SOURCE_UNKNOWN = (-1),
-+ GPIO_STEREO_SOURCE_D1,
-+ GPIO_STEREO_SOURCE_D2,
-+ GPIO_STEREO_SOURCE_D3,
-+ GPIO_STEREO_SOURCE_D4,
-+ GPIO_STEREO_SOURCE_D5,
-+ GPIO_STEREO_SOURCE_D6
-+};
-+
-+/*
-+ * GPIO config
-+ */
-+
-+enum gpio_config_type {
-+ GPIO_CONFIG_TYPE_NONE,
-+ GPIO_CONFIG_TYPE_DDC,
-+ GPIO_CONFIG_TYPE_HPD,
-+ GPIO_CONFIG_TYPE_GENERIC_MUX,
-+ GPIO_CONFIG_TYPE_GSL_MUX,
-+ GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE
-+};
-+
-+/* DDC configuration */
-+
-+enum gpio_ddc_config_type {
-+ GPIO_DDC_CONFIG_TYPE_MODE_AUX,
-+ GPIO_DDC_CONFIG_TYPE_MODE_I2C,
-+ GPIO_DDC_CONFIG_TYPE_POLL_FOR_CONNECT,
-+ GPIO_DDC_CONFIG_TYPE_POLL_FOR_DISCONNECT,
-+ GPIO_DDC_CONFIG_TYPE_DISABLE_POLLING
-+};
-+
-+struct gpio_ddc_config {
-+ enum gpio_ddc_config_type type;
-+ bool data_en_bit_present;
-+ bool clock_en_bit_present;
-+};
-+
-+/* HPD configuration */
-+
-+struct gpio_hpd_config {
-+ uint32_t delay_on_connect; /* milliseconds */
-+ uint32_t delay_on_disconnect; /* milliseconds */
-+};
-+
-+struct gpio_generic_mux_config {
-+ bool enable_output_from_mux;
-+ enum gpio_signal_source mux_select;
-+ enum gpio_stereo_source stereo_select;
-+};
-+
-+enum gpio_gsl_mux_config_type {
-+ GPIO_GSL_MUX_CONFIG_TYPE_DISABLE,
-+ GPIO_GSL_MUX_CONFIG_TYPE_TIMING_SYNC,
-+ GPIO_GSL_MUX_CONFIG_TYPE_FLIP_SYNC
-+};
-+
-+struct gpio_gsl_mux_config {
-+ enum gpio_gsl_mux_config_type type;
-+ /* Actually sync_source type,
-+ * however we want to avoid inter-component includes here */
-+ uint32_t gsl_group;
-+};
-+
-+struct gpio_config_data {
-+ enum gpio_config_type type;
-+ union {
-+ struct gpio_ddc_config ddc;
-+ struct gpio_hpd_config hpd;
-+ struct gpio_generic_mux_config generic_mux;
-+ struct gpio_gsl_mux_config gsl_mux;
-+ } config;
-+};
-+
-+struct gpio_ddc_hw_info {
-+ bool hw_supported;
-+ uint32_t ddc_channel;
-+};
-+
-+struct gpio_ddc_open_options {
-+ bool en_bit_present;
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/gpu_clock_info.h b/drivers/gpu/drm/amd/dal/include/gpu_clock_info.h
-new file mode 100644
-index 0000000..c9b47b2
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/gpu_clock_info.h
-@@ -0,0 +1,43 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_GPU_CLOCK_INFO__
-+#define __DAL_GPU_CLOCK_INFO__
-+
-+#include "include/gpu_interface.h"
-+
-+/*TODO this structures should be defined*/
-+struct gpu_static_clk_info;
-+struct gpu_dynamic_clk_info;
-+
-+bool init_static_clk_info(
-+ struct gpu *gpu,
-+ struct gpu_static_clk_info *st_clk_info);
-+
-+bool update_dynamic_clk_info(
-+ struct gpu *gpu,
-+ struct gpu_dynamic_clk_info *dyn_clk_info);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/gpu_interface.h b/drivers/gpu/drm/amd/dal/include/gpu_interface.h
-new file mode 100644
-index 0000000..63262c3
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/gpu_interface.h
-@@ -0,0 +1,91 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_GPU_INTERFACE__
-+#define __DAL_GPU_INTERFACE__
-+
-+#include "include/adapter_service_interface.h"
-+#include "include/grph_object_ctrl_defs.h"
-+
-+enum gpu_clocks_state {
-+ GPU_CLOCKS_STATE_INVALID,
-+ GPU_CLOCKS_STATE_ULTRA_LOW,
-+ GPU_CLOCKS_STATE_LOW,
-+ GPU_CLOCKS_STATE_NOMINAL,
-+ GPU_CLOCKS_STATE_PERFORMANCE
-+};
-+
-+struct gpu_clock_info {
-+ uint32_t min_sclk_khz;
-+ uint32_t max_sclk_khz;
-+
-+ uint32_t min_mclk_khz;
-+ uint32_t max_mclk_khz;
-+
-+ uint32_t min_dclk_khz;
-+ uint32_t max_dclk_khz;
-+};
-+
-+struct gpu;
-+struct irq_manager;
-+
-+struct gpu_init_data {
-+ struct dc_context *ctx;
-+ struct adapter_service *adapter_service;
-+ struct irq_manager *irq_manager;
-+};
-+
-+struct gpu *dal_gpu_create(struct gpu_init_data *init_data);
-+void dal_gpu_destroy(struct gpu **);
-+
-+void dal_gpu_power_up(struct gpu *);
-+void dal_gpu_power_down(
-+ struct gpu *gpu,
-+ enum dc_video_power_state power_state);
-+void dal_gpu_light_sleep_vbios_wa(struct gpu *gpu, bool enable);
-+void dal_gpu_release_hw(struct gpu *gpu);
-+
-+uint32_t dal_gpu_get_num_of_functional_controllers(const struct gpu *gpu);
-+uint32_t dal_gpu_get_max_num_of_primary_controllers(const struct gpu *gpu);
-+uint32_t dal_gpu_get_max_num_of_underlay_controllers(const struct gpu *gpu);
-+struct controller *dal_gpu_create_controller(
-+ struct gpu *gpu,
-+ uint32_t index);
-+uint32_t dal_gpu_get_num_of_clock_sources(const struct gpu *gpu);
-+struct clock_source *dal_gpu_create_clock_source(
-+ struct gpu *gpu,
-+ uint32_t index);
-+
-+/* gpu_clock_interface implementation */
-+bool dal_gpu_init_static_clock_info(struct gpu *gpu,
-+ struct gpu_clock_info *gpu_clk_info);
-+
-+bool dal_gpu_update_dynamic_clock_info(struct gpu *gpu,
-+ struct gpu_clock_info *gpu_clk_info);
-+
-+void dal_gpu_get_static_clock_info(struct gpu *gpu,
-+ struct gpu_clock_info *gpu_clk_info);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/grph_csc_types.h b/drivers/gpu/drm/amd/dal/include/grph_csc_types.h
-new file mode 100644
-index 0000000..711b458
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/grph_csc_types.h
-@@ -0,0 +1,98 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_GRPH_CSC_TYPES_H__
-+#define __DAL_GRPH_CSC_TYPES_H__
-+
-+#include "set_mode_types.h"
-+
-+enum color_space {
-+ COLOR_SPACE_UNKNOWN,
-+ COLOR_SPACE_SRGB_FULL_RANGE,
-+ COLOR_SPACE_SRGB_LIMITED_RANGE,
-+ COLOR_SPACE_YPBPR601,
-+ COLOR_SPACE_YPBPR709,
-+ COLOR_SPACE_YCBCR601,
-+ COLOR_SPACE_YCBCR709,
-+ COLOR_SPACE_YCBCR601_YONLY,
-+ COLOR_SPACE_YCBCR709_YONLY,
-+ COLOR_SPACE_N_MVPU_SUPER_AA,
-+};
-+
-+enum grph_color_adjust_option {
-+ GRPH_COLOR_MATRIX_HW_DEFAULT = 1,
-+ GRPH_COLOR_MATRIX_SW
-+};
-+
-+enum grph_csc_adjust_item {
-+ GRPH_ADJUSTMENT_CONTRAST = 1,
-+ GRPH_ADJUSTMENT_SATURATION,
-+ GRPH_ADJUSTMENT_BRIGHTNESS,
-+ GRPH_ADJUSTMENT_HUE,
-+ GRPH_ADJUSTMENT_COLOR_TEMPERATURE
-+};
-+
-+#define CSC_TEMPERATURE_MATRIX_SIZE 9
-+
-+enum graphics_csc_adjust_type {
-+ GRAPHICS_CSC_ADJUST_TYPE_BYPASS = 0,
-+ GRAPHICS_CSC_ADJUST_TYPE_HW, /* without adjustments */
-+ GRAPHICS_CSC_ADJUST_TYPE_SW /*use adjustments */
-+};
-+
-+enum graphics_gamut_adjust_type {
-+ GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS = 0,
-+ GRAPHICS_GAMUT_ADJUST_TYPE_HW, /* without adjustments */
-+ GRAPHICS_GAMUT_ADJUST_TYPE_SW /* use adjustments */
-+};
-+
-+struct grph_csc_adjustment {
-+ enum grph_color_adjust_option color_adjust_option;
-+ enum color_space c_space;
-+ int32_t grph_cont;
-+ int32_t grph_sat;
-+ int32_t grph_bright;
-+ int32_t grph_hue;
-+ int32_t adjust_divider;
-+ int32_t temperature_matrix[CSC_TEMPERATURE_MATRIX_SIZE];
-+ int32_t temperature_divider;
-+ uint32_t lb_color_depth;
-+ uint8_t gamma; /* gamma from Edid */
-+ enum dc_color_depth color_depth; /* clean up to uint32_t */
-+ enum pixel_format surface_pixel_format;
-+ enum graphics_csc_adjust_type csc_adjust_type;
-+ enum graphics_gamut_adjust_type gamut_adjust_type;
-+};
-+
-+struct default_adjustment {
-+ uint32_t lb_color_depth;
-+ enum color_space color_space;
-+ enum dc_color_depth color_depth;
-+ enum pixel_format surface_pixel_format;
-+ enum graphics_csc_adjust_type csc_adjust_type;
-+ bool force_hw_default;
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/grph_object_ctrl_defs.h b/drivers/gpu/drm/amd/dal/include/grph_object_ctrl_defs.h
-new file mode 100644
-index 0000000..d804109
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/grph_object_ctrl_defs.h
-@@ -0,0 +1,598 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_GRPH_OBJECT_CTRL_DEFS_H__
-+#define __DAL_GRPH_OBJECT_CTRL_DEFS_H__
-+
-+#include "grph_object_defs.h"
-+
-+/*
-+ * #####################################################
-+ * #####################################################
-+ *
-+ * These defines shared between asic_control/bios_parser and other
-+ * DAL components
-+ *
-+ * #####################################################
-+ * #####################################################
-+ */
-+
-+enum tv_standard {
-+ TV_STANDARD_UNKNOWN = 0, /* direct HW (mmBIOS_SCRATCH_2) translation! */
-+ TV_STANDARD_NTSC,
-+ TV_STANDARD_NTSCJ,
-+ TV_STANDARD_PAL,
-+ TV_STANDARD_PALM,
-+ TV_STANDARD_PALCN,
-+ TV_STANDARD_PALN,
-+ TV_STANDARD_PAL60,
-+ TV_STANDARD_SECAM
-+};
-+
-+enum cv_standard {
-+ CV_STANDARD_UNKNOWN = 0x0000,
-+ CV_STANDARD_HD_MASK = 0x0800, /* Flag mask HDTV output */
-+ CV_STANDARD_SD_NTSC_MASK = 0x1000, /* Flag mask NTSC output */
-+ CV_STANDARD_SD_NTSC_M, /* NTSC (North America) output 1001 */
-+ CV_STANDARD_SD_NTSC_J, /* NTSC (Japan) output 1002 */
-+ CV_STANDARD_SD_480I, /* SDTV 480i output 1003 */
-+ CV_STANDARD_SD_480P, /* SDTV 480p output 1004 */
-+ CV_STANDARD_HD_720_60P = 0x1800,/* HDTV 720/60p output 1800 */
-+ CV_STANDARD_HD_1080_60I, /* HDTV 1080/60i output 1801 */
-+ CV_STANDARD_SD_PAL_MASK = 0x2000,/* Flag mask PAL output */
-+ CV_STANDARD_SD_PAL_B, /* PAL B output 2001 */
-+ CV_STANDARD_SD_PAL_D, /* PAL D output 2002 */
-+ CV_STANDARD_SD_PAL_G, /* PAL G output 2003 */
-+ CV_STANDARD_SD_PAL_H, /* PAL H output 2004 */
-+ CV_STANDARD_SD_PAL_I, /* PAL I output 2005 */
-+ CV_STANDARD_SD_PAL_M, /* PAL M output 2006 */
-+ CV_STANDARD_SD_PAL_N, /* PAL N output 2007 */
-+ CV_STANDARD_SD_PAL_N_COMB, /* PAL Combination N output 2008 */
-+ CV_STANDARD_SD_PAL_60, /* PAL 60 output (test mode) 2009 */
-+ CV_STANDARD_SD_576I, /* SDTV 576i output 2010 */
-+ CV_STANDARD_SD_576P, /* SDTV 576p output 2011 */
-+ CV_STANDARD_HD_720_50P = 0x2800,/* HDTV 720/50p output 2800 */
-+ CV_STANDARD_HD_1080_50I, /* HDTV 1080/50i output 2801 */
-+ CV_STANDARD_SD_SECAM_MASK = 0x4000, /* Flag mask SECAM output */
-+ CV_STANDARD_SD_SECAM_B, /* SECAM B output 4001 */
-+ CV_STANDARD_SD_SECAM_D, /* SECAM D output 4002 */
-+ CV_STANDARD_SD_SECAM_G, /* SECAM G output 4003 */
-+ CV_STANDARD_SD_SECAM_H, /* SECAM H output 4004 */
-+ CV_STANDARD_SD_SECAM_K, /* SECAM K output 4005 */
-+ CV_STANDARD_SD_SECAM_K1, /* SECAM K1 output 4006 */
-+ CV_STANDARD_SD_SECAM_L, /* SECAM L output 4007 */
-+ CV_STANDARD_SD_SECAM_L1 /* SECAM L1 output 4009 */
-+};
-+
-+enum disp_pll_config {
-+ DISP_PLL_CONFIG_UNKNOWN = 0,
-+ DISP_PLL_CONFIG_DVO_DDR_MODE_LOW_12BIT,
-+ DISP_PLL_CONFIG_DVO_DDR_MODE_UPPER_12BIT,
-+ DISP_PLL_CONFIG_DVO_DDR_MODE_24BIT
-+};
-+
-+enum display_output_bit_depth {
-+ PANEL_UNDEFINE = 0,
-+ PANEL_6BIT_COLOR = 1,
-+ PANEL_8BIT_COLOR = 2,
-+ PANEL_10BIT_COLOR = 3,
-+ PANEL_12BIT_COLOR = 4,
-+ PANEL_16BIT_COLOR = 5,
-+};
-+
-+enum lcd_scale {
-+ /* No request to turn on LCD SCALER (Centering or Replication) */
-+ LCD_SCALE_NONE = 0,
-+ /* Request LCD SCALER in full panel mode */
-+ LCD_SCALE_FULLPANEL,
-+ /* Request LCD SCALER in aspect-ratio mode */
-+ LCD_SCALE_ASPECTRATIO,
-+
-+ LCD_SCALE_UNKNOWN = (-1L),
-+};
-+
-+/* Device type as abstracted by ATOM BIOS */
-+enum dal_device_type {
-+ DEVICE_TYPE_UNKNOWN = 0,
-+ DEVICE_TYPE_LCD,
-+ DEVICE_TYPE_CRT,
-+ DEVICE_TYPE_DFP,
-+ DEVICE_TYPE_CV,
-+ DEVICE_TYPE_TV,
-+ DEVICE_TYPE_CF,
-+ DEVICE_TYPE_WIRELESS
-+};
-+
-+/* Device ID as abstracted by ATOM BIOS */
-+struct device_id {
-+ enum dal_device_type device_type:16;
-+ uint32_t enum_id:16; /* 1 based enum */
-+};
-+
-+struct graphics_object_i2c_info {
-+ struct gpio_info {
-+ uint32_t clk_mask_register_index;
-+ uint32_t clk_en_register_index;
-+ uint32_t clk_y_register_index;
-+ uint32_t clk_a_register_index;
-+ uint32_t data_mask_register_index;
-+ uint32_t data_en_register_index;
-+ uint32_t data_y_register_index;
-+ uint32_t data_a_register_index;
-+
-+ uint32_t clk_mask_shift;
-+ uint32_t clk_en_shift;
-+ uint32_t clk_y_shift;
-+ uint32_t clk_a_shift;
-+ uint32_t data_mask_shift;
-+ uint32_t data_en_shift;
-+ uint32_t data_y_shift;
-+ uint32_t data_a_shift;
-+ } gpio_info;
-+
-+ bool i2c_hw_assist;
-+ uint32_t i2c_line;
-+ uint32_t i2c_engine_id;
-+ uint32_t i2c_slave_address;
-+};
-+
-+
-+struct graphics_object_hpd_info {
-+ uint8_t hpd_int_gpio_uid;
-+ uint8_t hpd_active;
-+};
-+
-+struct connector_device_tag_info {
-+ uint32_t acpi_device;
-+ struct device_id dev_id;
-+};
-+
-+struct device_timing {
-+ struct misc_info {
-+ uint32_t HORIZONTAL_CUT_OFF:1;
-+ /* 0=Active High, 1=Active Low */
-+ uint32_t H_SYNC_POLARITY:1;
-+ /* 0=Active High, 1=Active Low */
-+ uint32_t V_SYNC_POLARITY:1;
-+ uint32_t VERTICAL_CUT_OFF:1;
-+ uint32_t H_REPLICATION_BY2:1;
-+ uint32_t V_REPLICATION_BY2:1;
-+ uint32_t COMPOSITE_SYNC:1;
-+ uint32_t INTERLACE:1;
-+ uint32_t DOUBLE_CLOCK:1;
-+ uint32_t RGB888:1;
-+ uint32_t GREY_LEVEL:2;
-+ uint32_t SPATIAL:1;
-+ uint32_t TEMPORAL:1;
-+ uint32_t API_ENABLED:1;
-+ } misc_info;
-+
-+ uint32_t pixel_clk; /* in KHz */
-+ uint32_t horizontal_addressable;
-+ uint32_t horizontal_blanking_time;
-+ uint32_t vertical_addressable;
-+ uint32_t vertical_blanking_time;
-+ uint32_t horizontal_sync_offset;
-+ uint32_t horizontal_sync_width;
-+ uint32_t vertical_sync_offset;
-+ uint32_t vertical_sync_width;
-+ uint32_t horizontal_border;
-+ uint32_t vertical_border;
-+};
-+
-+struct supported_refresh_rate {
-+ uint32_t REFRESH_RATE_30HZ:1;
-+ uint32_t REFRESH_RATE_40HZ:1;
-+ uint32_t REFRESH_RATE_48HZ:1;
-+ uint32_t REFRESH_RATE_50HZ:1;
-+ uint32_t REFRESH_RATE_60HZ:1;
-+};
-+
-+struct embedded_panel_info {
-+ struct device_timing lcd_timing;
-+ uint32_t ss_id;
-+ struct supported_refresh_rate supported_rr;
-+ uint32_t drr_enabled;
-+ uint32_t min_drr_refresh_rate;
-+};
-+
-+struct embedded_panel_patch_mode {
-+ uint32_t width;
-+ uint32_t height;
-+};
-+
-+struct firmware_info {
-+ struct pll_info {
-+ uint32_t crystal_frequency; /* in KHz */
-+ uint32_t min_input_pxl_clk_pll_frequency; /* in KHz */
-+ uint32_t max_input_pxl_clk_pll_frequency; /* in KHz */
-+ uint32_t min_output_pxl_clk_pll_frequency; /* in KHz */
-+ uint32_t max_output_pxl_clk_pll_frequency; /* in KHz */
-+ } pll_info;
-+
-+ struct firmware_feature {
-+ uint32_t memory_clk_ss_percentage;
-+ uint32_t engine_clk_ss_percentage;
-+ } feature;
-+
-+ uint32_t default_display_engine_pll_frequency; /* in KHz */
-+ uint32_t external_clock_source_frequency_for_dp; /* in KHz */
-+ uint32_t smu_gpu_pll_output_freq; /* in KHz */
-+ uint8_t min_allowed_bl_level;
-+ uint8_t remote_display_config;
-+};
-+
-+/* direct HW (mmBIOS_SCRATCH_2) translation! */
-+union tv_standard_support {
-+ uint8_t u_all;
-+ struct {
-+ bool TV_SUPPORT_NTSC:1;
-+ bool TV_SUPPORT_NTSCJ:1;
-+
-+ bool TV_SUPPORT_PAL:1;
-+ bool TV_SUPPORT_PALM:1;
-+ bool TV_SUPPORT_PALCN:1;
-+ bool TV_SUPPORT_PALN:1;
-+ bool TV_SUPPORT_PAL60:1;
-+
-+ bool TV_SUPPORT_SECAM:1;
-+ } bits;
-+};
-+
-+struct analog_tv_info {
-+ union tv_standard_support tv_suppported;
-+ union tv_standard_support tv_boot_up_default;
-+};
-+
-+struct spread_spectrum_info {
-+ struct spread_spectrum_type {
-+ bool CENTER_MODE:1;
-+ bool EXTERNAL:1;
-+ bool STEP_AND_DELAY_INFO:1;
-+ } type;
-+
-+ /* in unit of 0.01% (spreadPercentageDivider = 100),
-+ otherwise in 0.001% units (spreadPercentageDivider = 1000); */
-+ uint32_t spread_spectrum_percentage;
-+ uint32_t spread_percentage_divider; /* 100 or 1000 */
-+ uint32_t spread_spectrum_range; /* modulation freq (HZ)*/
-+
-+ union {
-+ struct step_and_delay_info {
-+ uint32_t step;
-+ uint32_t delay;
-+ uint32_t recommended_ref_div;
-+ } step_and_delay_info;
-+ /* For mem/engine/uvd, Clock Out frequence (VCO ),
-+ in unit of kHz. For TMDS/HDMI/LVDS, it is pixel clock,
-+ for DP, it is link clock ( 270000 or 162000 ) */
-+ uint32_t target_clock_range; /* in KHz */
-+ };
-+
-+};
-+
-+struct graphics_object_encoder_cap_info {
-+ uint32_t dp_hbr2_cap:1;
-+ uint32_t dp_hbr2_validated:1;
-+ uint32_t reserved:15;
-+};
-+
-+struct din_connector_info {
-+ uint32_t gpio_id;
-+ bool gpio_tv_active_state;
-+};
-+
-+/* Invalid channel mapping */
-+enum { INVALID_DDI_CHANNEL_MAPPING = 0x0 };
-+
-+/**
-+ * DDI PHY channel mapping reflecting XBAR setting
-+ */
-+union ddi_channel_mapping {
-+ struct mapping {
-+ uint8_t lane0:2; /* Mapping for lane 0 */
-+ uint8_t lane1:2; /* Mapping for lane 1 */
-+ uint8_t lane2:2; /* Mapping for lane 2 */
-+ uint8_t lane3:2; /* Mapping for lane 3 */
-+ } mapping;
-+ uint8_t raw;
-+};
-+
-+/**
-+* Transmitter output configuration description
-+*/
-+struct transmitter_configuration_info {
-+ /* DDI PHY ID for the transmitter */
-+ enum transmitter transmitter_phy_id;
-+ /* DDI PHY channel mapping reflecting crossbar setting */
-+ union ddi_channel_mapping output_channel_mapping;
-+};
-+
-+struct transmitter_configuration {
-+ /* Configuration for the primary transmitter */
-+ struct transmitter_configuration_info primary_transmitter_config;
-+ /* Secondary transmitter configuration for Dual-link DVI */
-+ struct transmitter_configuration_info secondary_transmitter_config;
-+};
-+
-+
-+/* These size should be sufficient to store info coming from BIOS */
-+#define NUMBER_OF_UCHAR_FOR_GUID 16
-+#define MAX_NUMBER_OF_EXT_DISPLAY_PATH 7
-+#define NUMBER_OF_CSR_M3_ARB 10
-+#define NUMBER_OF_DISP_CLK_VOLTAGE 4
-+#define NUMBER_OF_AVAILABLE_SCLK 5
-+
-+/* V6 */
-+struct integrated_info {
-+ struct clock_voltage_caps {
-+ /* The Voltage Index indicated by FUSE, same voltage index
-+ shared with SCLK DPM fuse table */
-+ uint32_t voltage_index;
-+ /* Maximum clock supported with specified voltage index */
-+ uint32_t max_supported_clk; /* in KHz */
-+ } disp_clk_voltage[NUMBER_OF_DISP_CLK_VOLTAGE];
-+
-+ struct display_connection_info {
-+ struct external_display_path {
-+ /* A bit vector to show what devices are supported */
-+ uint32_t device_tag;
-+ /* 16bit device ACPI id. */
-+ uint32_t device_acpi_enum;
-+ /* A physical connector for displays to plug in,
-+ using object connector definitions */
-+ struct graphics_object_id device_connector_id;
-+ /* An index into external AUX/DDC channel LUT */
-+ uint8_t ext_aux_ddc_lut_index;
-+ /* An index into external HPD pin LUT */
-+ uint8_t ext_hpd_pin_lut_index;
-+ /* external encoder object id */
-+ struct graphics_object_id ext_encoder_obj_id;
-+ /* XBAR mapping of the PHY channels */
-+ union ddi_channel_mapping channel_mapping;
-+ } path[MAX_NUMBER_OF_EXT_DISPLAY_PATH];
-+
-+ uint8_t gu_id[NUMBER_OF_UCHAR_FOR_GUID];
-+ uint8_t checksum;
-+ } ext_disp_conn_info; /* exiting long long time */
-+
-+ struct available_s_clk_list {
-+ /* Maximum clock supported with specified voltage index */
-+ uint32_t supported_s_clk; /* in KHz */
-+ /* The Voltage Index indicated by FUSE for specified SCLK */
-+ uint32_t voltage_index;
-+ /* The Voltage ID indicated by FUSE for specified SCLK */
-+ uint32_t voltage_id;
-+ } avail_s_clk[NUMBER_OF_AVAILABLE_SCLK];
-+
-+ uint8_t memory_type;
-+ uint8_t ma_channel_number;
-+ uint32_t boot_up_engine_clock; /* in KHz */
-+ uint32_t dentist_vco_freq; /* in KHz */
-+ uint32_t boot_up_uma_clock; /* in KHz */
-+ uint32_t boot_up_req_display_vector;
-+ uint32_t other_display_misc;
-+ uint32_t gpu_cap_info;
-+ uint32_t sb_mmio_base_addr;
-+ uint32_t system_config;
-+ uint32_t cpu_cap_info;
-+ uint32_t max_nb_voltage;
-+ uint32_t min_nb_voltage;
-+ uint32_t boot_up_nb_voltage;
-+ uint32_t ext_disp_conn_info_offset;
-+ uint32_t csr_m3_arb_cntl_default[NUMBER_OF_CSR_M3_ARB];
-+ uint32_t csr_m3_arb_cntl_uvd[NUMBER_OF_CSR_M3_ARB];
-+ uint32_t csr_m3_arb_cntl_fs3d[NUMBER_OF_CSR_M3_ARB];
-+ uint32_t gmc_restore_reset_time;
-+ uint32_t minimum_n_clk;
-+ uint32_t idle_n_clk;
-+ uint32_t ddr_dll_power_up_time;
-+ uint32_t ddr_pll_power_up_time;
-+ /* start for V6 */
-+ uint32_t pcie_clk_ss_type;
-+ uint32_t lvds_ss_percentage;
-+ uint32_t lvds_sspread_rate_in_10hz;
-+ uint32_t hdmi_ss_percentage;
-+ uint32_t hdmi_sspread_rate_in_10hz;
-+ uint32_t dvi_ss_percentage;
-+ uint32_t dvi_sspread_rate_in_10_hz;
-+ uint32_t sclk_dpm_boost_margin;
-+ uint32_t sclk_dpm_throttle_margin;
-+ uint32_t sclk_dpm_tdp_limit_pg;
-+ uint32_t sclk_dpm_tdp_limit_boost;
-+ uint32_t boost_engine_clock;
-+ uint32_t boost_vid_2bit;
-+ uint32_t enable_boost;
-+ uint32_t gnb_tdp_limit;
-+ /* Start from V7 */
-+ uint32_t max_lvds_pclk_freq_in_single_link;
-+ uint32_t lvds_misc;
-+ uint32_t lvds_pwr_on_seq_dig_on_to_de_in_4ms;
-+ uint32_t lvds_pwr_on_seq_de_to_vary_bl_in_4ms;
-+ uint32_t lvds_pwr_off_seq_vary_bl_to_de_in4ms;
-+ uint32_t lvds_pwr_off_seq_de_to_dig_on_in4ms;
-+ uint32_t lvds_off_to_on_delay_in_4ms;
-+ uint32_t lvds_pwr_on_seq_vary_bl_to_blon_in_4ms;
-+ uint32_t lvds_pwr_off_seq_blon_to_vary_bl_in_4ms;
-+ uint32_t lvds_reserved1;
-+ uint32_t lvds_bit_depth_control_val;
-+};
-+
-+/**
-+* Power source ids.
-+*/
-+enum power_source {
-+ POWER_SOURCE_AC = 0,
-+ POWER_SOURCE_DC,
-+ POWER_SOURCE_LIMITED_POWER,
-+ POWER_SOURCE_LIMITED_POWER_2,
-+ POWER_SOURCE_MAX
-+};
-+
-+struct bios_event_info {
-+ uint32_t thermal_state;
-+ uint32_t backlight_level;
-+ enum power_source powerSource;
-+ bool has_thermal_state_changed;
-+ bool has_power_source_changed;
-+ bool has_forced_mode_changed;
-+ bool forced_mode;
-+ bool backlight_changed;
-+};
-+
-+union stereo_3d_support {
-+ struct {
-+ /* HW can alter left and right image sequentially */
-+ uint32_t FRAME_ALTERNATE:1;
-+ /* Frame Alternate + HW can integrate stereosync
-+ signal into TMDS stream */
-+ uint32_t DVI_FRAME_ALT:1;
-+ /* Frame Alternate + HW can integrate stereosync
-+ signal into DP stream */
-+ uint32_t DISPLAY_PORT_FRAME_ALT:1;
-+ /* Frame Alternate + HW can drive stereosync signal
-+ on separate line */
-+ uint32_t SIDEBAND_FRAME_ALT:1;
-+ /* SW allowed to pack left and right image into single frame.
-+ Used for HDMI only, DP has it's own flags. */
-+ uint32_t SW_FRAME_PACK:1;
-+ /* HW can pack left and right image into single HDMI frame */
-+ uint32_t PROGRESSIVE_FRAME_PACK:1;
-+ /* HW can pack left and right interlaced images into
-+ single HDMI frame */
-+ uint32_t INTERLACE_FRAME_PACK:1;
-+ /* HW can pack left and right images into single DP frame */
-+ uint32_t DISPLAY_PORT_FRAME_PACK:1;
-+ /* SW can pack left and right images into single DP frame */
-+ uint32_t DISPLAY_PORT_SW_FRAME_PACK:1;
-+ /* HW can mix left and right images into single image */
-+ uint32_t INTERLEAVE:1;
-+ /* HW can mix left and right interlaced images
-+ into single image */
-+ uint32_t INTERLACE_INTERLEAVE:1;
-+ /* Allow display-based formats (whatever supported)
-+ in WS stereo mode */
-+ uint32_t DISPLAY_3DIN_WS_MODE:1;
-+ /* Side-by-side, packed by application/driver into 2D frame */
-+ uint32_t SIDE_BY_SIDE_SW_PACKED:1;
-+ /* Top-and-bottom, packed by application/driver into 2D frame */
-+ uint32_t TOP_AND_BOTTOM_SW_PACKED:1;
-+ } bits;
-+ uint32_t u_all;
-+};
-+
-+/* Bitvector and bitfields of possible optimizations
-+ #IMPORTANT# Keep bitfields match bitvector! */
-+enum optimization_feature {
-+ /* Don't do HW programming on panels that were enabled by VBIOS */
-+ OF_SKIP_HW_PROGRAMMING_ON_ENABLED_EMBEDDED_DISPLAY = 0x1,
-+ OF_SKIP_RESET_OF_ALL_HW_ON_S3RESUME = 0x2,
-+ OF_SKIP_HW_RESET_OF_EMBEDDED_DISPLAY_ON_S3RESUME = 0x4,
-+ OF_SKIP_POWER_UP_VBIOS_ENABLED_ENCODER = 0x8,
-+ /* Do not turn off VCC while powering down on boot or resume */
-+ OF_KEEP_VCC_DURING_POWER_DOWN_ON_BOOT_OR_RESUME = 0x10,
-+ /* Do not turn off VCC while performing SetMode */
-+ OF_KEEP_VCC_DURING_SET_MODE = 0x20,
-+ OF_DO_NOT_WAIT_FOR_HPD_LOW = 0x40,
-+ OF_SKIP_POWER_DOWN_INACTIVE_ENCODER = 0x80
-+};
-+
-+union optimization_flags {
-+ struct {
-+ /* Don't do HW programming if panels were enabled by VBIOS */
-+ uint32_t SKIP_HW_PROGRAMMING_ON_ENABLED_EMBEDDED_DISPLAY:1;
-+ uint32_t SKIP_RESET_OF_ALL_HW_ON_S3RESUME:1;
-+ uint32_t SKIP_HW_RESET_OF_EMBEDDED_DISPLAY_ON_S3RESUME:1;
-+ uint32_t SKIP_POWER_UP_VBIOS_ENABLED_ENCODER:1;
-+ /* Do not turn off VCC while powering down on boot or resume */
-+ uint32_t KEEP_VCC_DURING_POWER_DOWN_ON_BOOT_OR_RESUME:1;
-+ /* Do not turn off VCC while performing SetMode */
-+ uint32_t KEEP_VCC_DURING_SET_MODE:1;
-+ uint32_t DO_NOT_WAIT_FOR_HPD_LOW:1;
-+ } bits;
-+ uint32_t u_all;
-+};
-+
-+/* Bitvector and bitfields of performance measurements
-+ #IMPORTANT# Keep bitfields match bitvector! */
-+enum perf_measure {
-+ PERF_MEASURE_ADAPTER_POWER_STATE = 0x1,
-+ PERF_MEASURE_DISPLAY_POWER_STATE = 0x2,
-+ PERF_MEASURE_SET_MODE_SEQ = 0x4,
-+ PERF_MEASURE_DETECT_AT_RESUME = 0x8,
-+ PERF_MEASURE_MEMORY_READ_CONTROL = 0x10,
-+};
-+
-+union perf_measure_flags {
-+ struct {
-+ uint32_t ADAPTER_POWER_STATE:1;
-+ uint32_t DISPLAY_POWER_STATE:1;
-+ uint32_t SET_MODE_SEQ:1;
-+ uint32_t DETECT_AT_RESUME:1;
-+ uint32_t MEMORY_READ_CONTROL:1;
-+
-+ } bits;
-+ uint32_t u_all;
-+};
-+
-+enum {
-+ PERF_MEASURE_POWERCODE_OFFSET = 0x0,
-+ PERF_MEASURE_POWER_CODE_MASK = 0xFF,
-+ PERF_MEASURE_POWER_STATE_OFFSET = 8,
-+ PERF_MEASURE_POWER_STATE_MASK = 0x000FF00,
-+ PERF_MEASURE_PREV_POWER_STATE_OFFSET = 16,
-+ PERF_MEASURE_PREV_POWER_STATE_MASK = 0x00FF0000,
-+ PERF_MEASURE_DISPLAY_INDEX_OFFSET = 24,
-+ PERF_MEASURE_DISPLAY_INDEX_MASK = 0xFF000000
-+};
-+
-+enum {
-+ HDMI_PIXEL_CLOCK_IN_KHZ_297 = 297000,
-+ TMDS_PIXEL_CLOCK_IN_KHZ_165 = 165000
-+};
-+
-+/*
-+ * DFS-bypass flag
-+ */
-+/* Copy of SYS_INFO_GPUCAPS__ENABEL_DFS_BYPASS from atombios.h */
-+enum {
-+ DFS_BYPASS_ENABLE = 0x10
-+};
-+
-+enum {
-+ INVALID_BACKLIGHT = -1
-+};
-+
-+struct panel_backlight_boundaries {
-+ uint32_t min_signal_level;
-+ uint32_t max_signal_level;
-+};
-+
-+struct panel_backlight_default_levels {
-+ uint32_t ac_level_percentage;
-+ uint32_t dc_level_percentage;
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/grph_object_defs.h b/drivers/gpu/drm/amd/dal/include/grph_object_defs.h
-new file mode 100644
-index 0000000..a1e468f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/grph_object_defs.h
-@@ -0,0 +1,328 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_GRPH_OBJECT_DEFS_H__
-+#define __DAL_GRPH_OBJECT_DEFS_H__
-+
-+#include "grph_object_id.h"
-+
-+/* ********************************************************************
-+ * ********************************************************************
-+ *
-+ * These defines shared between All Graphics Objects
-+ *
-+ * ********************************************************************
-+ * ********************************************************************
-+ */
-+
-+/* HPD unit id - HW direct translation */
-+enum hpd_source_id {
-+ HPD_SOURCEID1 = 0,
-+ HPD_SOURCEID2,
-+ HPD_SOURCEID3,
-+ HPD_SOURCEID4,
-+ HPD_SOURCEID5,
-+ HPD_SOURCEID6,
-+
-+ HPD_SOURCEID_COUNT,
-+ HPD_SOURCEID_UNKNOWN
-+};
-+
-+/* DDC unit id - HW direct translation */
-+enum channel_id {
-+ CHANNEL_ID_UNKNOWN = 0,
-+ CHANNEL_ID_DDC1,
-+ CHANNEL_ID_DDC2,
-+ CHANNEL_ID_DDC3,
-+ CHANNEL_ID_DDC4,
-+ CHANNEL_ID_DDC5,
-+ CHANNEL_ID_DDC6,
-+ CHANNEL_ID_DDC_VGA,
-+ CHANNEL_ID_I2C_PAD,
-+ CHANNEL_ID_COUNT
-+};
-+
-+#define DECODE_CHANNEL_ID(ch_id) \
-+ (ch_id) == CHANNEL_ID_DDC1 ? "CHANNEL_ID_DDC1" : \
-+ (ch_id) == CHANNEL_ID_DDC2 ? "CHANNEL_ID_DDC2" : \
-+ (ch_id) == CHANNEL_ID_DDC3 ? "CHANNEL_ID_DDC3" : \
-+ (ch_id) == CHANNEL_ID_DDC4 ? "CHANNEL_ID_DDC4" : \
-+ (ch_id) == CHANNEL_ID_DDC5 ? "CHANNEL_ID_DDC5" : \
-+ (ch_id) == CHANNEL_ID_DDC6 ? "CHANNEL_ID_DDC6" : \
-+ (ch_id) == CHANNEL_ID_DDC_VGA ? "CHANNEL_ID_DDC_VGA" : \
-+ (ch_id) == CHANNEL_ID_I2C_PAD ? "CHANNEL_ID_I2C_PAD" : "Invalid"
-+
-+enum transmitter {
-+ TRANSMITTER_UNKNOWN = (-1L),
-+ TRANSMITTER_UNIPHY_A,
-+ TRANSMITTER_UNIPHY_B,
-+ TRANSMITTER_UNIPHY_C,
-+ TRANSMITTER_UNIPHY_D,
-+ TRANSMITTER_UNIPHY_E,
-+ TRANSMITTER_UNIPHY_F,
-+ TRANSMITTER_NUTMEG_CRT,
-+ TRANSMITTER_TRAVIS_CRT,
-+ TRANSMITTER_TRAVIS_LCD,
-+ TRANSMITTER_UNIPHY_G,
-+ TRANSMITTER_COUNT
-+};
-+
-+enum physical_phy_id {
-+ PHY_ID_UNKNOWN = (-1L),
-+ PHY_ID_0,
-+ PHY_ID_1,
-+ PHY_ID_2,
-+ PHY_ID_3,
-+ PHY_ID_4,
-+ PHY_ID_5,
-+ PHY_ID_6,
-+ PHY_ID_7,
-+ PHY_ID_8,
-+ PHY_ID_9,
-+ PHY_ID_COUNT
-+};
-+
-+/* Generic source of the synchronisation input/output signal */
-+/* Can be used for flow control, stereo sync, timing sync, frame sync, etc */
-+enum sync_source {
-+ SYNC_SOURCE_NONE = 0,
-+
-+ /* Source based on controllers */
-+ SYNC_SOURCE_CONTROLLER0,
-+ SYNC_SOURCE_CONTROLLER1,
-+ SYNC_SOURCE_CONTROLLER2,
-+ SYNC_SOURCE_CONTROLLER3,
-+ SYNC_SOURCE_CONTROLLER4,
-+ SYNC_SOURCE_CONTROLLER5,
-+
-+ /* Source based on GSL group */
-+ SYNC_SOURCE_GSL_GROUP0,
-+ SYNC_SOURCE_GSL_GROUP1,
-+ SYNC_SOURCE_GSL_GROUP2,
-+
-+ /* Source based on GSL IOs */
-+ /* These IOs normally used as GSL input/output */
-+ SYNC_SOURCE_GSL_IO_FIRST,
-+ SYNC_SOURCE_GSL_IO_GENLOCK_CLOCK = SYNC_SOURCE_GSL_IO_FIRST,
-+ SYNC_SOURCE_GSL_IO_GENLOCK_VSYNC,
-+ SYNC_SOURCE_GSL_IO_SWAPLOCK_A,
-+ SYNC_SOURCE_GSL_IO_SWAPLOCK_B,
-+ SYNC_SOURCE_GSL_IO_LAST = SYNC_SOURCE_GSL_IO_SWAPLOCK_B,
-+
-+ /* Source based on regular IOs */
-+ SYNC_SOURCE_IO_FIRST,
-+ SYNC_SOURCE_IO_GENERIC_A = SYNC_SOURCE_IO_FIRST,
-+ SYNC_SOURCE_IO_GENERIC_B,
-+ SYNC_SOURCE_IO_GENERIC_C,
-+ SYNC_SOURCE_IO_GENERIC_D,
-+ SYNC_SOURCE_IO_GENERIC_E,
-+ SYNC_SOURCE_IO_GENERIC_F,
-+ SYNC_SOURCE_IO_HPD1,
-+ SYNC_SOURCE_IO_HPD2,
-+ SYNC_SOURCE_IO_HSYNC_A,
-+ SYNC_SOURCE_IO_VSYNC_A,
-+ SYNC_SOURCE_IO_HSYNC_B,
-+ SYNC_SOURCE_IO_VSYNC_B,
-+ SYNC_SOURCE_IO_LAST = SYNC_SOURCE_IO_VSYNC_B,
-+
-+ /* Misc. flow control sources */
-+ SYNC_SOURCE_DUAL_GPU_PIN
-+};
-+
-+enum trigger_edge {
-+ TRIGGER_EDGE_RISING = 0,
-+ TRIGGER_EDGE_FALLING,
-+ TRIGGER_EDGE_BOTH,
-+ TRIGGER_EDGE_DEFAULT
-+};
-+
-+/* Parameters to enable CRTC trigger */
-+struct trigger_params {
-+ enum sync_source source;
-+ enum trigger_edge edge;
-+};
-+
-+/* CRTC Static Screen event triggers */
-+struct static_screen_events {
-+ union {
-+ /* event mask to enable/disable various
-+ trigger sources for static screen detection */
-+ struct {
-+ /* Force event high */
-+ uint32_t FRAME_START:1;
-+ /* Cursor register change */
-+ uint32_t CURSOR_MOVE:1;
-+ /* Memory write to any client other than MCIF */
-+ uint32_t MEM_WRITE:1;
-+ /* Memory write to hit memory region 0 */
-+ uint32_t MEM_REGION0_WRITE:1;
-+ /* Memory write to hit memory region 1 */
-+ uint32_t MEM_REGION1_WRITE:1;
-+ /* Memory write to hit memory region 2 */
-+ uint32_t MEM_REGION2_WRITE:1;
-+ /* Memory write to hit memory region 3 */
-+ uint32_t MEM_REGION3_WRITE:1;
-+ /* Graphics Surface Update Pending */
-+ uint32_t GFX_UPDATE:1;
-+ /* Overlay Surface Update Pending */
-+ uint32_t OVL_UPDATE:1;
-+ /* Compressed surface invalidated in FBC */
-+ uint32_t INVALIDATE_FBC_SURFACE:1;
-+ /* Register pending update in any double buffered
-+ register group in the display pipe
-+ (i.e. Blender, DCP, or SCL) */
-+ uint32_t REG_PENDING_UPDATE:1;
-+ /* Crtc_trig_a: Based on signal from any other CRTC */
-+ uint32_t CRTC_TRIG_A:1;
-+ /* Crtc_trig_b: Based on signal from any other CRTC */
-+ uint32_t CRTC_TRIG_B:1;
-+ /* Readback of CRTC nominal vertical count register
-+ by driver indicates that OS may be trying to change
-+ mode or contents of the display therefore need to
-+ switch to higher refresh rate */
-+ uint32_t READBACK_NOMINAL_VERTICAL:1;
-+ /* Readback of CRTC dynamic vertical count register
-+ by driver indicates that OS may be trying to change
-+ mode or contents of the display therefore need to
-+ switch to higher refresh rate */
-+ uint32_t READBACK_DYNAMIC_VERTICAL:1;
-+ /* Reserved */
-+ uint32_t RESERVED:1;
-+ } bits;
-+ uint32_t u_all;
-+ };
-+};
-+
-+
-+/*
-+ * ***************************************************************
-+ * ********************* Register programming sequences ********
-+ * ***************************************************************
-+ */
-+
-+/* GPIO/Register access sequences */
-+enum io_register_sequence {
-+ /* GLSync sequences to access SwapReady & SwapRequest
-+ GPIOs - GLSync Connector parameter */
-+ IO_REG_SEQUENCE_SWAPREADY_SET = 0,
-+ IO_REG_SEQUENCE_SWAPREADY_RESET,
-+ IO_REG_SEQUENCE_SWAPREADY_READ,
-+ IO_REG_SEQUENCE_SWAPREQUEST_SET,
-+ IO_REG_SEQUENCE_SWAPREQUEST_RESET,
-+ IO_REG_SEQUENCE_SWAPREQUEST_READ,
-+
-+ /* Frame synchronization start/stop - display index parameter */
-+ IO_REG_SEQUENCE_FRAMELOCK_STOP,
-+ IO_REG_SEQUENCE_FRAMELOCK_START,
-+
-+ /* Flip lock/unlock - GLSync Connector parameter */
-+ IO_REG_SEQUENCE_GLOBALSWAP_LOCK,
-+ IO_REG_SEQUENCE_GLOBALSWAP_UNLOCK,
-+
-+ IO_REG_SEQUENCEENUM_MAX
-+};
-+
-+#define IO_REGISTER_SEQUENCE_MAX_LENGTH 5
-+
-+/*
-+ *****************************************************************************
-+ * struct io_register
-+ *****************************************************************************
-+ * Generic struct for read/write register or GPIO.
-+ * It allows controlling only some bit section of register, rather then the
-+ * whole one.
-+ * For write operation should be used as following:
-+ * 1. data = READ(Base + RegisterOffset)
-+ * 2. data &= ANDMask
-+ * 3. data |= ORMask
-+ * 4. WRITE(Base + RegisterOffset, data)
-+ *
-+ * Note: In case of regular register, ANDMask will be typically 0.
-+ * In case of GPIO, ANDMask will have typically all bits set
-+ * except the specific GPIO bit.
-+ *
-+ * For read operation should be used as following:
-+ * 1. data = READ(Base + RegisterOffset)
-+ * 2. data &= ANDMask
-+ * 3. data >>= BitShift
-+ *
-+ * Note: In case of regular register, ANDMask will be typically 0xFFFFFFFF.
-+ * In case of GPIO, ANDMask will have typically only specific GPIO bit set
-+ *
-+ * Note: Base Address is not exposed in this structure due to
-+ * security consideration.
-+ */
-+
-+/*
-+ * The generic sequence to program/access registers or GPIOs.
-+ * There could be 2 types of sequences - read and write.
-+ * Read sequence may have 0 or more writes and in the end one read
-+ * Write sequence may have 1 or more writes.
-+ */
-+struct io_reg_sequence {
-+ /* Ordered array of register to program */
-+ struct {
-+ /* Offset of memory mapped register or GPIO */
-+ uint32_t register_offset;
-+ /* Mask to use at AND operation (Mandatory, comes
-+ before OR operation) */
-+ uint32_t and_mask;
-+ union {
-+ /* Mask to use at OR operation (For write
-+ sequence only, comes after AND operation) */
-+ uint32_t or_mask;
-+ /* Number of bits to shift to get the actual value
-+ (For read sequence only, comes after AND operation) */
-+ uint32_t bit_shift;
-+ };
-+ } io_registers[IO_REGISTER_SEQUENCE_MAX_LENGTH];
-+
-+ uint32_t steps_num; /* Total number of r/w steps in the sequence */
-+};
-+
-+/* Sequence ID - uniqly defines sequence on single adapter */
-+struct io_reg_sequence_id {
-+ enum io_register_sequence sequence; /* Sequence enumeration Index/ID */
-+ union {
-+ /* Refers to object to which the sequence applies.*/
-+ uint32_t index;
-+ uint32_t display_index;
-+ uint32_t controller_index;
-+ uint32_t glsync_connector_index;
-+ };
-+};
-+
-+struct fbc_info {
-+ bool fbc_enable;
-+ bool lpt_enable;
-+};
-+
-+/* Event to request TM change IRQ registration state */
-+struct hotplug_irq_data {
-+ bool disable;
-+ struct graphics_object_id connector;
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/grph_object_id.h b/drivers/gpu/drm/amd/dal/include/grph_object_id.h
-new file mode 100644
-index 0000000..fcf3eea
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/grph_object_id.h
-@@ -0,0 +1,285 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_GRPH_OBJECT_ID_H__
-+#define __DAL_GRPH_OBJECT_ID_H__
-+
-+/* Types of graphics objects */
-+enum object_type {
-+ OBJECT_TYPE_UNKNOWN = 0,
-+
-+ /* Direct ATOM BIOS translation */
-+ OBJECT_TYPE_GPU,
-+ OBJECT_TYPE_ENCODER,
-+ OBJECT_TYPE_CONNECTOR,
-+ OBJECT_TYPE_ROUTER,
-+ OBJECT_TYPE_GENERIC,
-+
-+ /* Driver specific */
-+ OBJECT_TYPE_AUDIO,
-+ OBJECT_TYPE_CONTROLLER,
-+ OBJECT_TYPE_CLOCK_SOURCE,
-+ OBJECT_TYPE_ENGINE,
-+
-+ OBJECT_TYPE_COUNT
-+};
-+
-+/* Enumeration inside one type of graphics objects */
-+enum object_enum_id {
-+ ENUM_ID_UNKNOWN = 0,
-+ ENUM_ID_1,
-+ ENUM_ID_2,
-+ ENUM_ID_3,
-+ ENUM_ID_4,
-+ ENUM_ID_5,
-+ ENUM_ID_6,
-+ ENUM_ID_7,
-+
-+ ENUM_ID_COUNT
-+};
-+
-+/* Generic object ids */
-+enum generic_id {
-+ GENERIC_ID_UNKNOWN = 0,
-+ GENERIC_ID_MXM_OPM,
-+ GENERIC_ID_GLSYNC,
-+ GENERIC_ID_STEREO,
-+
-+ GENERIC_ID_COUNT
-+};
-+
-+/* Controller object ids */
-+enum controller_id {
-+ CONTROLLER_ID_UNDEFINED = 0,
-+ CONTROLLER_ID_D0,
-+ CONTROLLER_ID_D1,
-+ CONTROLLER_ID_D2,
-+ CONTROLLER_ID_D3,
-+ CONTROLLER_ID_D4,
-+ CONTROLLER_ID_D5,
-+ CONTROLLER_ID_UNDERLAY0,
-+ CONTROLLER_ID_MAX = CONTROLLER_ID_UNDERLAY0
-+};
-+
-+#define IS_UNDERLAY_CONTROLLER(ctrlr_id) (ctrlr_id >= CONTROLLER_ID_UNDERLAY0)
-+
-+/*
-+ * ClockSource object ids.
-+ * We maintain the order matching (more or less) ATOM BIOS
-+ * to improve optimized acquire
-+ */
-+enum clock_source_id {
-+ CLOCK_SOURCE_ID_UNDEFINED = 0,
-+ CLOCK_SOURCE_ID_PLL0,
-+ CLOCK_SOURCE_ID_PLL1,
-+ CLOCK_SOURCE_ID_PLL2,
-+ CLOCK_SOURCE_ID_EXTERNAL, /* ID (Phy) ref. clk. for DP */
-+ CLOCK_SOURCE_ID_DCPLL,
-+ CLOCK_SOURCE_ID_DFS, /* DENTIST */
-+ CLOCK_SOURCE_ID_VCE, /* VCE does not need a real PLL */
-+ CLOCK_SOURCE_ID_DP_DTO, /* Used to distinguish between */
-+ /* programming pixel clock */
-+ /* and ID (Phy) clock */
-+};
-+
-+
-+/* Encoder object ids */
-+enum encoder_id {
-+ ENCODER_ID_UNKNOWN = 0,
-+
-+ /* Radeon Class Display Hardware */
-+ ENCODER_ID_INTERNAL_LVDS,
-+ ENCODER_ID_INTERNAL_TMDS1,
-+ ENCODER_ID_INTERNAL_TMDS2,
-+ ENCODER_ID_INTERNAL_DAC1,
-+ ENCODER_ID_INTERNAL_DAC2, /* TV/CV DAC */
-+ ENCODER_ID_INTERNAL_SDVOA,
-+ ENCODER_ID_INTERNAL_SDVOB,
-+
-+ /* External Third Party Encoders */
-+ ENCODER_ID_EXTERNAL_SI170B,
-+ ENCODER_ID_EXTERNAL_CH7303,
-+ ENCODER_ID_EXTERNAL_CH7301, /* 10 in decimal */
-+ ENCODER_ID_INTERNAL_DVO1, /* Belongs to Radeon Display Hardware */
-+ ENCODER_ID_EXTERNAL_SDVOA,
-+ ENCODER_ID_EXTERNAL_SDVOB,
-+ ENCODER_ID_EXTERNAL_TITFP513,
-+ ENCODER_ID_INTERNAL_LVTM1, /* not used for Radeon */
-+ ENCODER_ID_EXTERNAL_VT1623,
-+ ENCODER_ID_EXTERNAL_SI1930, /* HDMI */
-+ ENCODER_ID_INTERNAL_HDMI,
-+
-+ /* Kaledisope (KLDSCP) Class Display Hardware */
-+ ENCODER_ID_INTERNAL_KLDSCP_TMDS1,
-+ ENCODER_ID_INTERNAL_KLDSCP_DVO1,
-+ ENCODER_ID_INTERNAL_KLDSCP_DAC1,
-+ ENCODER_ID_INTERNAL_KLDSCP_DAC2, /* Shared with CV/TV and CRT */
-+ /* External TMDS (dual link) */
-+ ENCODER_ID_EXTERNAL_SI178,
-+ ENCODER_ID_EXTERNAL_MVPU_FPGA, /* MVPU FPGA chip */
-+ ENCODER_ID_INTERNAL_DDI,
-+ ENCODER_ID_EXTERNAL_VT1625,
-+ ENCODER_ID_EXTERNAL_SI1932,
-+ ENCODER_ID_EXTERNAL_AN9801, /* External Display Port */
-+ ENCODER_ID_EXTERNAL_DP501, /* External Display Port */
-+ ENCODER_ID_INTERNAL_UNIPHY,
-+ ENCODER_ID_INTERNAL_KLDSCP_LVTMA,
-+ ENCODER_ID_INTERNAL_UNIPHY1,
-+ ENCODER_ID_INTERNAL_UNIPHY2,
-+ ENCODER_ID_EXTERNAL_NUTMEG,
-+ ENCODER_ID_EXTERNAL_TRAVIS,
-+
-+ ENCODER_ID_INTERNAL_WIRELESS, /* Internal wireless display encoder */
-+ ENCODER_ID_INTERNAL_UNIPHY3,
-+
-+ ENCODER_ID_EXTERNAL_GENERIC_DVO = 0xFF
-+};
-+
-+
-+/* Connector object ids */
-+enum connector_id {
-+ CONNECTOR_ID_UNKNOWN = 0,
-+ CONNECTOR_ID_SINGLE_LINK_DVII,
-+ CONNECTOR_ID_DUAL_LINK_DVII,
-+ CONNECTOR_ID_SINGLE_LINK_DVID,
-+ CONNECTOR_ID_DUAL_LINK_DVID,
-+ CONNECTOR_ID_VGA,
-+ CONNECTOR_ID_HDMI_TYPE_A,
-+ CONNECTOR_ID_NOT_USED,
-+ CONNECTOR_ID_LVDS,
-+ CONNECTOR_ID_PCIE,
-+ CONNECTOR_ID_HARDCODE_DVI,
-+ CONNECTOR_ID_DISPLAY_PORT,
-+ CONNECTOR_ID_EDP,
-+ CONNECTOR_ID_MXM,
-+ CONNECTOR_ID_WIRELESS, /* wireless display pseudo-connector */
-+ CONNECTOR_ID_MIRACAST, /* used for VCE encode display path
-+ * for Miracast */
-+
-+ CONNECTOR_ID_COUNT
-+};
-+
-+
-+/* Audio object ids */
-+enum audio_id {
-+ AUDIO_ID_UNKNOWN = 0,
-+ AUDIO_ID_INTERNAL_AZALIA
-+};
-+
-+
-+/* Engine object ids */
-+enum engine_id {
-+ ENGINE_ID_DIGA,
-+ ENGINE_ID_DIGB,
-+ ENGINE_ID_DIGC,
-+ ENGINE_ID_DIGD,
-+ ENGINE_ID_DIGE,
-+ ENGINE_ID_DIGF,
-+ ENGINE_ID_DIGG,
-+ ENGINE_ID_DVO,
-+ ENGINE_ID_DACA,
-+ ENGINE_ID_DACB,
-+ ENGINE_ID_VCE, /* wireless display pseudo-encoder */
-+
-+ ENGINE_ID_COUNT,
-+ ENGINE_ID_UNKNOWN = (-1L)
-+};
-+
-+union supported_stream_engines {
-+ struct {
-+ uint32_t ENGINE_ID_DIGA:1;
-+ uint32_t ENGINE_ID_DIGB:1;
-+ uint32_t ENGINE_ID_DIGC:1;
-+ uint32_t ENGINE_ID_DIGD:1;
-+ uint32_t ENGINE_ID_DIGE:1;
-+ uint32_t ENGINE_ID_DIGF:1;
-+ uint32_t ENGINE_ID_DIGG:1;
-+ uint32_t ENGINE_ID_DVO:1;
-+ uint32_t ENGINE_ID_DACA:1;
-+ uint32_t ENGINE_ID_DACB:1;
-+ uint32_t ENGINE_ID_VCE:1;
-+ } engine;
-+ uint32_t u_all;
-+};
-+
-+
-+/*
-+ *****************************************************************************
-+ * graphics_object_id struct
-+ *
-+ * graphics_object_id is a very simple struct wrapping 32bit Graphics
-+ * Object identication
-+ *
-+ * This struct should stay very simple
-+ * No dependencies at all (no includes)
-+ * No debug messages or asserts
-+ * No #ifndef and preprocessor directives
-+ * No grow in space (no more data member)
-+ *****************************************************************************
-+ */
-+
-+struct graphics_object_id {
-+ uint32_t id:8;
-+ uint32_t enum_id:4;
-+ uint32_t type:4;
-+ uint32_t reserved:16; /* for padding. total size should be u32 */
-+};
-+
-+/* some simple functions for convenient graphics_object_id handle */
-+
-+static inline struct graphics_object_id dal_graphics_object_id_init(
-+ uint32_t id,
-+ enum object_enum_id enum_id,
-+ enum object_type type)
-+{
-+ struct graphics_object_id result = {
-+ id, enum_id, type, 0
-+ };
-+
-+ return result;
-+}
-+
-+bool dal_graphics_object_id_is_valid(
-+ struct graphics_object_id id);
-+bool dal_graphics_object_id_is_equal(
-+ struct graphics_object_id id1,
-+ struct graphics_object_id id2);
-+uint32_t dal_graphics_object_id_to_uint(
-+ struct graphics_object_id id);
-+
-+
-+enum controller_id dal_graphics_object_id_get_controller_id(
-+ struct graphics_object_id id);
-+enum clock_source_id dal_graphics_object_id_get_clock_source_id(
-+ struct graphics_object_id id);
-+enum encoder_id dal_graphics_object_id_get_encoder_id(
-+ struct graphics_object_id id);
-+enum connector_id dal_graphics_object_id_get_connector_id(
-+ struct graphics_object_id id);
-+enum audio_id dal_graphics_object_id_get_audio_id(
-+ struct graphics_object_id id);
-+enum engine_id dal_graphics_object_id_get_engine_id(
-+ struct graphics_object_id id);
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/hw_adjustment_set.h b/drivers/gpu/drm/amd/dal/include/hw_adjustment_set.h
-new file mode 100644
-index 0000000..10fb8e2
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/hw_adjustment_set.h
-@@ -0,0 +1,50 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_ADJUSTMENT_SET_H__
-+#define __DAL_HW_ADJUSTMENT_SET_H__
-+
-+#include "include/hw_adjustment_types.h"
-+
-+struct hw_adjustment_gamma_ramp;
-+
-+struct hw_adjustment_set {
-+ struct hw_adjustment_gamma_ramp *gamma_ramp;
-+ struct hw_adjustment_deflicker *deflicker_filter;
-+ struct hw_adjustment_value *coherent;
-+ struct hw_adjustment_value *h_sync;
-+ struct hw_adjustment_value *v_sync;
-+ struct hw_adjustment_value *composite_sync;
-+ struct hw_adjustment_value *backlight;
-+ struct hw_adjustment_value *vb_level;
-+ struct hw_adjustment_color_control *color_control;
-+ union hw_adjustment_bit_depth_reduction *bit_depth;
-+};
-+/*
-+struct hw_adjustment *dal_adjustment_set_get_by_id(
-+ struct hw_adjustment_set *adjustment_set,
-+ enum hw_adjustment_id id);*/
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/hw_adjustment_types.h b/drivers/gpu/drm/amd/dal/include/hw_adjustment_types.h
-new file mode 100644
-index 0000000..cfae832
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/hw_adjustment_types.h
-@@ -0,0 +1,205 @@
-+#ifndef __DAL_HW_ADJUSTMENT_TYPES_H__
-+#define __DAL_HW_ADJUSTMENT_TYPES_H__
-+
-+#include "hw_sequencer_types.h"
-+
-+enum hw_adjustment_id {
-+ HW_ADJUSTMENT_ID_COLOR_CONTROL,
-+ HW_ADJUSTMENT_ID_GAMMA_LUT,
-+ HW_ADJUSTMENT_ID_GAMMA_RAMP,
-+ HW_ADJUSTMENT_ID_DEFLICKER,
-+ HW_ADJUSTMENT_ID_SHARPNESS_CONTROL,
-+ HW_ADJUSTMENT_ID_TIMING,
-+ HW_ADJUSTMENT_ID_TIMING_AND_PIXEL_CLOCK,
-+ HW_ADJUSTMENT_ID_OVERSCAN,
-+ HW_ADJUSTMENT_ID_UNDERSCAN_TYPE,
-+ HW_ADJUSTMENT_ID_VERTICAL_SYNC,
-+ HW_ADJUSTMENT_ID_HORIZONTAL_SYNC,
-+ HW_ADJUSTMENT_ID_COMPOSITE_SYNC,
-+ HW_ADJUSTMENT_ID_VIDEO_STANDARD,
-+ HW_ADJUSTMENT_ID_BACKLIGHT,
-+ HW_ADJUSTMENT_ID_BIT_DEPTH_REDUCTION,
-+ HW_ADJUSTMENT_ID_REDUCED_BLANKING,
-+ HW_ADJUSTMENT_ID_COHERENT,
-+ /* OVERLAY ADJUSTMENTS*/
-+ HW_ADJUSTMENT_ID_OVERLAY,
-+ HW_ADJUSTMENT_ID_OVERLAY_ALPHA,
-+ HW_ADJUSTMENT_ID_OVERLAY_VARIABLE_GAMMA,
-+ HW_ADJUSTMENT_ID_COUNT,
-+ HW_ADJUSTMENT_ID_UNDEFINED,
-+};
-+
-+struct hw_adjustment_deflicker {
-+ int32_t hp_factor;
-+ uint32_t hp_divider;
-+ int32_t lp_factor;
-+ uint32_t lp_divider;
-+ int32_t sharpness;
-+ bool enable_sharpening;
-+};
-+
-+struct hw_adjustment_value {
-+ union {
-+ uint32_t ui_value;
-+ int32_t i_value;
-+ };
-+};
-+
-+enum hw_color_adjust_option {
-+ HWS_COLOR_MATRIX_HW_DEFAULT = 1,
-+ HWS_COLOR_MATRIX_SW
-+};
-+
-+enum {
-+ HW_TEMPERATURE_MATRIX_SIZE = 9,
-+ HW_TEMPERATURE_MATRIX_SIZE_WITH_OFFSET = 12
-+};
-+
-+struct hw_adjustment_color_control {
-+ enum hw_color_space color_space;
-+ enum hw_color_adjust_option option;
-+ enum pixel_format surface_pixel_format;
-+ enum dc_color_depth color_depth;
-+ uint32_t lb_color_depth;
-+ int32_t contrast;
-+ int32_t saturation;
-+ int32_t brightness;
-+ int32_t hue;
-+ uint32_t adjust_divider;
-+ uint32_t temperature_divider;
-+ uint32_t temperature_matrix[HW_TEMPERATURE_MATRIX_SIZE];
-+};
-+
-+struct hw_underscan_adjustment {
-+ struct hw_adjustment_deflicker deflicker;
-+ struct overscan_info hw_overscan;
-+};
-+
-+struct hw_underscan_adjustment_data {
-+ enum hw_adjustment_id hw_adj_id;
-+ struct hw_underscan_adjustment hw_underscan_adj;
-+};
-+
-+union hw_adjustment_bit_depth_reduction {
-+ uint32_t raw;
-+ struct {
-+ uint32_t TRUNCATE_ENABLED:1;
-+ uint32_t TRUNCATE_DEPTH:2;
-+ uint32_t TRUNCATE_MODE:1;
-+ uint32_t SPATIAL_DITHER_ENABLED:1;
-+ uint32_t SPATIAL_DITHER_DEPTH:2;
-+ uint32_t SPATIAL_DITHER_MODE:2;
-+ uint32_t RGB_RANDOM:1;
-+ uint32_t FRAME_RANDOM:1;
-+ uint32_t HIGHPASS_RANDOM:1;
-+ uint32_t FRAME_MODULATION_ENABLED:1;
-+ uint32_t FRAME_MODULATION_DEPTH:2;
-+ uint32_t TEMPORAL_LEVEL:1;
-+ uint32_t FRC_25:2;
-+ uint32_t FRC_50:2;
-+ uint32_t FRC_75:2;
-+ } bits;
-+};
-+
-+struct hw_color_control_range {
-+ struct hw_adjustment_range contrast;
-+ struct hw_adjustment_range saturation;
-+ struct hw_adjustment_range brightness;
-+ struct hw_adjustment_range hue;
-+ struct hw_adjustment_range temperature;
-+};
-+
-+enum hw_surface_type {
-+ HW_OVERLAY_SURFACE = 1,
-+ HW_GRAPHIC_SURFACE
-+};
-+
-+/* LUT type for GammaCorrection */
-+struct hw_gamma_lut {
-+ uint32_t red;
-+ uint32_t green;
-+ uint32_t blue;
-+};
-+
-+struct hw_devc_lut {
-+ uint8_t red;
-+ uint8_t green;
-+ uint8_t blue;
-+ uint8_t reserved;
-+};
-+
-+struct hw_adjustment_gamma_lut {
-+ struct hw_gamma_lut *pGammaLut;
-+ uint32_t size_in_elements;
-+ enum pixel_format surface_pixel_format;
-+};
-+
-+
-+enum hw_gamma_ramp_type {
-+ HW_GAMMA_RAMP_UNITIALIZED = 0,
-+ HW_GAMMA_RAMP_DEFAULT,
-+ HW_GAMMA_RAMP_RBG_256x3x16,
-+ HW_GAMMA_RAMP_RBG_DXGI_1
-+};
-+
-+#define HW_GAMMA_RAMP_RBG_256 256
-+
-+struct hw_gamma_ramp_rgb256x3x16 {
-+ unsigned short red[HW_GAMMA_RAMP_RBG_256];
-+ unsigned short green[HW_GAMMA_RAMP_RBG_256];
-+ unsigned short blue[HW_GAMMA_RAMP_RBG_256];
-+};
-+
-+union hw_gamma_flags {
-+ uint32_t raw;
-+ struct {
-+ uint32_t gamma_ramp_array :1;
-+ uint32_t graphics_degamma_srgb :1;
-+ uint32_t overlay_degamma_srgb :1;
-+ uint32_t apply_degamma :1;
-+ uint32_t reserved :28;
-+ } bits;
-+};
-+
-+struct hw_regamma_coefficients {
-+ int32_t gamma[3];
-+ int32_t a0[3];
-+ int32_t a1[3];
-+ int32_t a2[3];
-+ int32_t a3[3];
-+};
-+
-+struct hw_regamma_ramp {
-+ /* Gamma ramp packed as RGB */
-+ unsigned short gamma[256 * 3];
-+};
-+
-+struct hw_regamma_lut {
-+ union hw_gamma_flags flags;
-+ union {
-+ struct hw_regamma_ramp gamma;
-+ struct hw_regamma_coefficients coeff;
-+ };
-+};
-+
-+union hw_gamma_flag {
-+ uint32_t uint;
-+ struct {
-+ uint32_t config_is_changed :1;
-+ uint32_t regamma_update :1;
-+ uint32_t gamma_update :1;
-+ uint32_t reserved :29;
-+ } bits;
-+};
-+
-+struct hw_adjustment_gamma_ramp {
-+ uint32_t size;
-+ enum hw_gamma_ramp_type type;
-+ enum pixel_format surface_pixel_format;
-+ enum hw_color_space color_space;
-+ struct hw_regamma_lut regamma;
-+ union hw_gamma_flag flag;
-+ struct hw_gamma_ramp_rgb256x3x16 gamma_ramp_rgb256x3x16;
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/hw_path_mode_set_interface.h b/drivers/gpu/drm/amd/dal/include/hw_path_mode_set_interface.h
-new file mode 100644
-index 0000000..28ac018
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/hw_path_mode_set_interface.h
-@@ -0,0 +1,48 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_PATH_MODE_SET_INTERFACE_H__
-+#define __DAL_HW_PATH_MODE_SET_INTERFACE_H__
-+
-+struct hw_path_mode;
-+struct hw_path_mode_set;
-+
-+struct hw_path_mode_set *dal_hw_path_mode_set_create(void);
-+
-+void dal_hw_path_mode_set_destroy(struct hw_path_mode_set **set);
-+
-+bool dal_hw_path_mode_set_add(
-+ struct hw_path_mode_set *set,
-+ struct hw_path_mode *path_mode,
-+ uint32_t *index);
-+
-+struct hw_path_mode *dal_hw_path_mode_set_get_path_by_index(
-+ const struct hw_path_mode_set *set,
-+ uint32_t index);
-+
-+uint32_t dal_hw_path_mode_set_get_paths_number(
-+ const struct hw_path_mode_set *set);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/hw_sequencer_interface.h b/drivers/gpu/drm/amd/dal/include/hw_sequencer_interface.h
-new file mode 100644
-index 0000000..ddd78d6
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/hw_sequencer_interface.h
-@@ -0,0 +1,388 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_SEQUENCER_INTERFACE_H__
-+#define __DAL_HW_SEQUENCER_INTERFACE_H__
-+
-+#include "hw_sequencer_types.h"
-+#include "hw_adjustment_types.h"
-+#include "include/display_clock_interface.h"
-+#include "include/scaler_types.h"
-+#include "include/grph_csc_types.h"
-+#include "plane_types.h"
-+
-+#include "adapter_service_interface.h"
-+
-+enum hwss_result {
-+ HWSS_RESULT_OK,
-+ HWSS_RESULT_ERROR,
-+ HWSS_RESULT_NO_BANDWIDTH,
-+ HWSS_RESULT_OUT_OF_RANGE,
-+ HWSS_RESULT_NOT_SUPPORTED,
-+ HWSS_RESULT_UNKNOWN
-+};
-+
-+struct hws_init_data {
-+ struct adapter_service *as;
-+ struct dal_context *dal_context;
-+};
-+
-+/* TODO: below is three almost equal structures.
-+ * We should decide what to do with them */
-+struct blank_stream_param {
-+ struct display_path *display_path;
-+ uint32_t link_idx;
-+ struct hw_crtc_timing timing;
-+ struct link_settings link_settings;
-+};
-+
-+struct enable_stream_param {
-+ struct display_path *display_path;
-+ uint32_t link_idx;
-+ struct hw_crtc_timing timing;
-+ struct link_settings link_settings;
-+
-+ const struct hw_path_mode *path_mode;
-+};
-+
-+struct enable_link_param {
-+ struct display_path *display_path;
-+ uint32_t link_idx;
-+ struct hw_crtc_timing timing;
-+ struct link_settings link_settings;
-+
-+ bool optimized_programming;
-+ const struct hw_path_mode *path_mode;
-+};
-+
-+struct validate_link_param {
-+ const struct display_path *display_path;
-+ uint32_t link_idx;
-+ struct link_settings link_settings;
-+};
-+
-+struct set_dp_phy_pattern_param {
-+ struct display_path *display_path;
-+ uint32_t link_idx;
-+ enum dp_test_pattern test_pattern;
-+ const uint8_t *custom_pattern;
-+ uint32_t cust_pattern_size;
-+};
-+
-+struct hw_global_objects;
-+struct hw_sequencer;
-+struct hw_adjustment;
-+struct hw_path_mode_set;
-+struct hw_path_mode;
-+struct hwss_build_params;
-+struct controller;
-+
-+void dal_hw_sequencer_mute_audio_endpoint(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path,
-+ bool mute);
-+
-+void dal_hw_sequencer_enable_audio_endpoint(
-+ struct hw_sequencer *hws,
-+ struct link_settings *ls,
-+ struct display_path *display_path,
-+ bool enable);
-+
-+enum hwss_result dal_hw_sequencer_reset_audio_device(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path);
-+
-+enum hwss_result dal_hw_sequencer_validate_link(
-+ struct hw_sequencer *hws,
-+ const struct validate_link_param *param);
-+
-+bool dal_hw_sequencer_is_supported_dp_training_pattern3(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path,
-+ uint32_t link_idx);
-+
-+enum hwss_result dal_hw_sequencer_set_dp_phy_pattern(
-+ struct hw_sequencer *hws,
-+ const struct set_dp_phy_pattern_param *param);
-+
-+enum hwss_result dal_hw_sequencer_set_lane_settings(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path,
-+ const struct link_training_settings *link_settings);
-+
-+void dal_hw_sequencer_set_test_pattern(
-+ struct hw_sequencer *hws,
-+ struct hw_path_mode *path_mode,
-+ enum dp_test_pattern test_pattern,
-+ const struct link_training_settings *link_settings,
-+ const uint8_t *custom_pattern,
-+ uint8_t cust_pattern_size);
-+
-+bool dal_hw_sequencer_has_audio_bandwidth_changed(
-+ struct hw_sequencer *hws,
-+ const struct hw_path_mode *old,
-+ const struct hw_path_mode *new);
-+
-+void dal_hw_sequencer_enable_azalia_audio_jack_presence(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path);
-+
-+void dal_hw_sequencer_disable_azalia_audio_jack_presence(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path);
-+
-+void dal_hw_sequencer_enable_memory_requests(
-+ struct hw_sequencer *hws,
-+ struct hw_path_mode *path_mode);
-+
-+void dal_hw_sequencer_update_info_packets(
-+ struct hw_sequencer *hws,
-+ struct hw_path_mode *path_mode);
-+
-+/* Static validation for a SINGLE path mode.
-+ * Already "active" paths (if any) are NOT taken into account. */
-+enum hwss_result dal_hw_sequencer_validate_display_path_mode(
-+ struct hw_sequencer *hws,
-+ const struct hw_path_mode *path_mode);
-+
-+/* Validation for a SET of path modes, including Video Memory Bandwidth
-+ * validation. */
-+enum hwss_result dal_hw_sequencer_validate_display_hwpms(
-+ struct hw_sequencer *hws,
-+ struct hw_path_mode_set *path_set);
-+
-+struct hw_adjustment_gamma_ramp;
-+
-+enum hwss_result dal_hw_sequencer_set_gamma_ramp_adjustment(
-+ struct hw_sequencer *hws,
-+ const struct display_path *display_path,
-+ struct hw_adjustment_gamma_ramp *adjusment);
-+
-+enum hwss_result dal_hw_sequencer_set_color_control_adjustment(
-+ struct hw_sequencer *hws,
-+ struct controller *crtc,
-+ struct hw_adjustment_color_control *adjustment);
-+
-+enum hwss_result dal_hw_sequencer_set_vertical_sync_adjustment(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path,
-+ struct hw_adjustment_value *adjustment);
-+
-+enum hwss_result dal_hw_sequencer_set_horizontal_sync_adjustment(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path,
-+ struct hw_adjustment_value *adjustment);
-+
-+enum hwss_result dal_hw_sequencer_set_composite_sync_adjustment(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path,
-+ struct hw_adjustment_value *adjustment);
-+
-+enum hwss_result dal_hw_sequencer_enable_sync_output(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path);
-+
-+enum hwss_result dal_hw_sequencer_disable_sync_output(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path);
-+
-+enum hwss_result dal_hw_sequencer_set_backlight_adjustment(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path,
-+ struct hw_adjustment_value *adjustment);
-+
-+void dal_hw_sequencer_disable_memory_requests(
-+ struct hw_sequencer *hws,
-+ const struct hw_path_mode *path_mode);
-+
-+enum hwss_result dal_hw_sequencer_enable_link(
-+ struct hw_sequencer *hws,
-+ const struct enable_link_param *in);
-+
-+void dal_hw_sequencer_disable_link(
-+ struct hw_sequencer *hws,
-+ const struct enable_link_param *in);
-+
-+void dal_hw_sequencer_enable_stream(
-+ struct hw_sequencer *hws,
-+ const struct enable_stream_param *in);
-+
-+void dal_hw_sequencer_disable_stream(
-+ struct hw_sequencer *hws,
-+ const struct enable_stream_param *in);
-+
-+void dal_hw_sequencer_blank_stream(
-+ struct hw_sequencer *hws,
-+ const struct blank_stream_param *in);
-+
-+void dal_hw_sequencer_unblank_stream(
-+ struct hw_sequencer *hws,
-+ const struct blank_stream_param *in);
-+
-+enum hwss_result dal_hw_sequencer_set_clocks_and_clock_state(
-+ struct hw_sequencer *hws,
-+ struct hw_global_objects *g_obj,
-+ const struct minimum_clocks_calculation_result *min_clk_in,
-+ enum clocks_state required_clocks_state);
-+
-+enum hwss_result dal_hw_sequencer_set_mode(
-+ struct hw_sequencer *hws,
-+ struct hw_path_mode_set *path_set);
-+
-+enum signal_type dal_hw_sequencer_detect_sink(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path);
-+
-+enum signal_type dal_hw_sequencer_detect_load(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path);
-+
-+bool dal_hw_sequencer_is_sink_present(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path);
-+
-+void dal_hw_sequencer_psr_setup(
-+ struct hw_sequencer *hws,
-+ const struct hw_path_mode *path_mode,
-+ const struct psr_caps *psr_caps);
-+
-+void dal_hw_sequencer_psr_enable(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path);
-+
-+void dal_hw_sequencer_psr_disable(
-+ struct hw_sequencer *hws,
-+ struct display_path *display_path);
-+
-+void dal_hw_sequencer_program_drr(
-+ struct hw_sequencer *hws,
-+ const struct hw_path_mode *path_mode);
-+
-+enum hwss_result dal_hw_sequencer_set_safe_displaymark(
-+ struct hw_sequencer *hws,
-+ struct hw_path_mode_set *path_set);
-+
-+enum hwss_result dal_hw_sequencer_set_displaymark(
-+ struct hw_sequencer *hws,
-+ struct hw_path_mode_set *path_set);
-+
-+void dal_hw_sequencer_destroy(struct hw_sequencer **hws);
-+
-+struct hw_sequencer *dal_hw_sequencer_create(
-+ struct hws_init_data *hws_init_data);
-+
-+enum hwss_result dal_hw_sequencer_set_overscan_adj(
-+ struct hw_sequencer *hws,
-+ struct hw_path_mode_set *set,
-+ struct hw_underscan_adjustment_data *hw_underscan);
-+
-+bool dal_hw_sequencer_enable_line_buffer_power_gating(
-+ struct line_buffer *lb,
-+ enum controller_id id,
-+ enum pixel_type pixel_type,
-+ uint32_t src_pixel_width,
-+ uint32_t dst_pixel_width,
-+ struct scaling_taps *taps,
-+ enum lb_pixel_depth lb_depth,
-+ uint32_t src_height,
-+ uint32_t dst_height,
-+ bool interlaced);
-+
-+void dal_hw_sequencer_build_scaler_parameter(
-+ const struct hw_path_mode *path_mode,
-+ const struct scaling_taps *taps,
-+ bool build_timing_required,
-+ struct scaler_data *scaler_data);
-+
-+void dal_hw_sequencer_update_info_frame(
-+ const struct hw_path_mode *hw_path_mode);
-+
-+enum hwss_result dal_hw_sequencer_set_bit_depth_reduction_adj(
-+ struct hw_sequencer *hws,
-+ struct display_path *disp_path,
-+ union hw_adjustment_bit_depth_reduction *bit_depth);
-+
-+bool dal_hw_sequencer_is_support_custom_gamut_adj(
-+ struct hw_sequencer *hws,
-+ struct display_path *disp_path,
-+ enum hw_surface_type surface_type);
-+
-+enum hwss_result dal_hw_sequencer_get_hw_color_adj_range(
-+ struct hw_sequencer *hws,
-+ struct display_path *disp_path,
-+ struct hw_color_control_range *hw_color_range);
-+
-+bool dal_hw_sequencer_is_support_custom_gamma_coefficients(
-+ struct hw_sequencer *hws,
-+ struct display_path *disp_path,
-+ enum hw_surface_type surface_type);
-+
-+enum hwss_result dal_hw_sequencer_build_csc_adjust(
-+ struct hw_sequencer *hws,
-+ struct hw_adjustment_color_control *color_control,
-+ struct grph_csc_adjustment *adjust);
-+
-+void dal_hw_sequencer_build_gamma_ramp_adj_params(
-+ const struct hw_adjustment_gamma_ramp *adjusment,
-+ struct gamma_parameters *gamma_param,
-+ struct gamma_ramp *ramp);
-+
-+void translate_from_hw_to_controller_regamma(
-+ const struct hw_regamma_lut *hw_regamma,
-+ struct regamma_lut *regamma);
-+
-+void dal_hw_sequencer_enable_wireless_idle_detection(
-+ struct hw_sequencer *hws,
-+ bool enable);
-+
-+/* Cursor interface */
-+enum hwss_result dal_hw_sequencer_set_cursor_position(
-+ struct hw_sequencer *hws,
-+ struct display_path *dp,
-+ const struct dc_cursor_position *position);
-+
-+enum hwss_result dal_hw_sequencer_set_cursor_attributes(
-+ struct hw_sequencer *hws,
-+ struct display_path *dp,
-+ const struct dc_cursor_attributes *attributes);
-+
-+/* Underlay/MPO interface */
-+enum hwss_result dal_hw_sequencer_set_plane_config(
-+ struct hw_sequencer *hws,
-+ struct hw_path_mode_set *path_set,
-+ uint32_t display_index);
-+
-+bool dal_hw_sequencer_update_plane_address(
-+ struct hw_sequencer *hws,
-+ struct display_path *dp,
-+ uint32_t num_planes,
-+ struct plane_addr_flip_info *info);
-+
-+void dal_hw_sequencer_prepare_to_release_planes(
-+ struct hw_sequencer *hws,
-+ struct hw_path_mode_set *path_set,
-+ uint32_t display_index);
-+
-+#endif /* __DAL_HW_SEQUENCER_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/hw_sequencer_types.h b/drivers/gpu/drm/amd/dal/include/hw_sequencer_types.h
-new file mode 100644
-index 0000000..d5d7059
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/hw_sequencer_types.h
-@@ -0,0 +1,305 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_SEQUENCER_TYPES_H__
-+#define __DAL_HW_SEQUENCER_TYPES_H__
-+
-+#include "signal_types.h"
-+#include "grph_object_defs.h"
-+#include "link_service_types.h"
-+#include "plane_types.h"
-+
-+struct color_quality {
-+ uint32_t bpp_graphics;
-+ uint32_t bpp_backend_video;
-+};
-+
-+enum {
-+ HW_MAX_NUM_VIEWPORTS = 2,
-+ HW_CURRENT_PIPE_INDEX = 0,
-+ HW_OTHER_PIPE_INDEX = 1
-+};
-+
-+struct hw_view_port_adjustment {
-+ int32_t start_adjustment;
-+ int32_t width;
-+
-+ enum controller_id controller_id;
-+};
-+
-+struct hw_view_port_adjustments {
-+ uint32_t view_ports_num;
-+ struct hw_view_port_adjustment adjustments[HW_MAX_NUM_VIEWPORTS];
-+};
-+
-+/* Timing standard */
-+enum hw_timing_standard {
-+ HW_TIMING_STANDARD_UNDEFINED,
-+ HW_TIMING_STANDARD_DMT,
-+ HW_TIMING_STANDARD_GTF,
-+ HW_TIMING_STANDARD_CVT,
-+ HW_TIMING_STANDARD_CVT_RB,
-+ HW_TIMING_STANDARD_CEA770,
-+ HW_TIMING_STANDARD_CEA861,
-+ HW_TIMING_STANDARD_HDMI,
-+ HW_TIMING_STANDARD_TV_NTSC,
-+ HW_TIMING_STANDARD_TV_NTSC_J,
-+ HW_TIMING_STANDARD_TV_PAL,
-+ HW_TIMING_STANDARD_TV_PAL_M,
-+ HW_TIMING_STANDARD_TV_PAL_CN,
-+ HW_TIMING_STANDARD_TV_SECAM,
-+ /* for explicit timings from VBIOS, EDID etc. */
-+ HW_TIMING_STANDARD_EXPLICIT
-+};
-+
-+/* identical to struct crtc_ranged_timing_control
-+ * defined in controller\timing_generator_types.h */
-+struct hw_ranged_timing_control {
-+ /* set to 1 to force dynamic counter V_COUNT
-+ * to lock to constant rate counter V_COUNT_NOM
-+ * on page flip event in dynamic refresh mode
-+ * when switching from a low refresh rate to nominal refresh rate */
-+ bool force_lock_on_event;
-+ /* set to 1 to force CRTC2 (slave) to lock to CRTC1 (master) VSync
-+ * in order to overlap their blank regions for MC clock changes */
-+ bool lock_to_master_vsync;
-+
-+ /* set to 1 to program Static Screen Detection Masks
-+ * without enabling dynamic refresh rate */
-+ bool program_static_screen_mask;
-+ /* set to 1 to program Dynamic Refresh Rate */
-+ bool program_dynamic_refresh_rate;
-+ /* set to 1 to force disable Dynamic Refresh Rate */
-+ bool force_disable_drr;
-+
-+ /* event mask to enable/disable various trigger sources
-+ * for static screen detection */
-+ struct static_screen_events event_mask;
-+
-+ /* Number of consecutive static screen frames before static state is
-+ * asserted. */
-+ uint32_t static_frame_count;
-+};
-+
-+/* define the structure of Dynamic Refresh Mode */
-+struct hw_ranged_timing {
-+ /* defines the minimum possible vertical dimension of display timing
-+ * for CRTC as supported by the panel */
-+ uint32_t vertical_total_min;
-+ /* defines the maximum possible vertical dimension of display timing
-+ * for CRTC as supported by the panel */
-+ uint32_t vertical_total_max;
-+
-+ struct hw_ranged_timing_control control;
-+};
-+
-+/* CRTC timing structure */
-+struct hw_crtc_timing {
-+ uint32_t h_total;
-+ uint32_t h_addressable;
-+ uint32_t h_overscan_left;
-+ uint32_t h_overscan_right;
-+ uint32_t h_sync_start;
-+ uint32_t h_sync_width;
-+
-+ uint32_t v_total;
-+ uint32_t v_addressable;
-+ uint32_t v_overscan_top;
-+ uint32_t v_overscan_bottom;
-+ uint32_t v_sync_start;
-+ uint32_t v_sync_width;
-+
-+ struct hw_ranged_timing ranged_timing;
-+
-+ /* in KHz */
-+ uint32_t pixel_clock;
-+
-+ enum hw_timing_standard timing_standard;
-+ enum dc_color_depth color_depth;
-+ enum dc_pixel_encoding pixel_encoding;
-+
-+ struct {
-+ uint32_t INTERLACED:1;
-+ uint32_t DOUBLESCAN:1;
-+ uint32_t PIXEL_REPETITION:4; /* 1...10 */
-+ uint32_t HSYNC_POSITIVE_POLARITY:1;
-+ uint32_t VSYNC_POSITIVE_POLARITY:1;
-+ /* frame should be packed for 3D
-+ * (currently this refers to HDMI 1.4a FramePacking format */
-+ uint32_t HORZ_COUNT_BY_TWO:1;
-+ uint32_t PACK_3D_FRAME:1;
-+ /* 0 - left eye polarity, 1 - right eye polarity */
-+ uint32_t RIGHT_EYE_3D_POLARITY:1;
-+ /* DVI-DL High-Color mode */
-+ uint32_t HIGH_COLOR_DL_MODE:1;
-+ uint32_t Y_ONLY:1;
-+ /* HDMI 2.0 - Support scrambling for TMDS character
-+ * rates less than or equal to 340Mcsc */
-+ uint32_t LTE_340MCSC_SCRAMBLE:1;
-+ } flags;
-+};
-+
-+struct hw_scaling_info {
-+ struct view src;
-+ struct view dst;
-+ enum signal_type signal;
-+};
-+
-+enum hw_color_space {
-+ HW_COLOR_SPACE_UNKNOWN = 0,
-+ HW_COLOR_SPACE_SRGB_FULL_RANGE,
-+ HW_COLOR_SPACE_SRGB_LIMITED_RANGE,
-+ HW_COLOR_SPACE_YPBPR601,
-+ HW_COLOR_SPACE_YPBPR709,
-+ HW_COLOR_SPACE_YCBCR601,
-+ HW_COLOR_SPACE_YCBCR709,
-+ HW_COLOR_SPACE_YCBCR601_YONLY,
-+ HW_COLOR_SPACE_YCBCR709_YONLY,
-+ HW_COLOR_SPACE_NMVPU_SUPERAA,
-+};
-+
-+enum hw_overlay_color_space {
-+ HW_OVERLAY_COLOR_SPACE_UNKNOWN,
-+ HW_OVERLAY_COLOR_SPACE_BT709,
-+ HW_OVERLAY_COLOR_SPACE_BT601,
-+ HW_OVERLAY_COLOR_SPACE_SMPTE240,
-+ HW_OVERLAY_COLOR_SPACE_RGB
-+};
-+
-+enum hw_overlay_backend_bpp {
-+ HW_OVERLAY_BACKEND_BPP_UNKNOWN,
-+ HW_OVERLAY_BACKEND_BPP32_FULL_BANDWIDTH,
-+ HW_OVERLAY_BACKEND_BPP16_FULL_BANDWIDTH,
-+ HW_OVERLAY_BACKEND_BPP32_HALF_BANDWIDTH,
-+};
-+enum hw_overlay_format {
-+ HW_OVERLAY_FORMAT_UNKNOWN,
-+ HW_OVERLAY_FORMAT_YUY2,
-+ HW_OVERLAY_FORMAT_UYVY,
-+ HW_OVERLAY_FORMAT_RGB565,
-+ HW_OVERLAY_FORMAT_RGB555,
-+ HW_OVERLAY_FORMAT_RGB32,
-+ HW_OVERLAY_FORMAT_YUV444,
-+ HW_OVERLAY_FORMAT_RGB32_2101010
-+};
-+
-+enum hw_scale_options {
-+ HW_SCALE_OPTION_UNKNOWN,
-+ HW_SCALE_OPTION_OVERSCAN, /* multimedia pass through mode */
-+ HW_SCALE_OPTION_UNDERSCAN
-+};
-+
-+enum hw_stereo_format {
-+ HW_STEREO_FORMAT_NONE = 0,
-+ HW_STEREO_FORMAT_SIDE_BY_SIDE = 1,
-+ HW_STEREO_FORMAT_TOP_AND_BOTTOM = 2,
-+ HW_STEREO_FORMAT_FRAME_ALTERNATE = 3,
-+ HW_STEREO_FORMAT_ROW_INTERLEAVED = 5,
-+ HW_STEREO_FORMAT_COLUMN_INTERLEAVED = 6,
-+ HW_STEREO_FORMAT_CHECKER_BOARD = 7 /* the same as pixel interleave */
-+};
-+
-+enum hw_dithering_options {
-+ HW_DITHERING_OPTION_UNKNOWN,
-+ HW_DITHERING_OPTION_SKIP_PROGRAMMING,
-+ HW_DITHERING_OPTION_ENABLE,
-+ HW_DITHERING_OPTION_DISABLE
-+};
-+
-+struct hw_stereo_mixer_params {
-+ bool sub_sampling;
-+ bool single_pipe;
-+};
-+
-+
-+
-+struct hw_action_flags {
-+ uint32_t RESYNC_PATH:1;
-+ uint32_t TIMING_CHANGED:1;
-+ uint32_t PIXEL_ENCODING_CHANGED:1;
-+ uint32_t GAMUT_CHANGED:1;
-+ uint32_t TURN_OFF_VCC:1;
-+};
-+
-+enum hw_sync_request {
-+ HW_SYNC_REQUEST_NONE = 0,
-+ HW_SYNC_REQUEST_SET_INTERPATH,
-+ HW_SYNC_REQUEST_SET_GL_SYNC_GENLOCK,
-+ HW_SYNC_REQUEST_SET_GL_SYNC_FREE_RUN,
-+ HW_SYNC_REQUEST_SET_GL_SYNC_SHADOW,
-+ HW_SYNC_REQUEST_RESET_GLSYNC,
-+ HW_SYNC_REQUEST_RESYNC_GLSYNC,
-+ HW_SYNC_REQUEST_SET_STEREO3D
-+};
-+
-+struct hw_sync_info {
-+ enum hw_sync_request sync_request;
-+ uint32_t target_pixel_clock; /* in KHz */
-+ enum sync_source sync_source;
-+};
-+
-+/* TODO hw_info_frame and hw_info_packet structures are same as in encoder
-+ * merge it*/
-+struct hw_info_packet {
-+ bool valid;
-+ uint8_t hb0;
-+ uint8_t hb1;
-+ uint8_t hb2;
-+ uint8_t hb3;
-+ uint8_t sb[28];
-+};
-+
-+struct hw_info_frame {
-+ /* Auxiliary Video Information */
-+ struct hw_info_packet avi_info_packet;
-+ struct hw_info_packet gamut_packet;
-+ struct hw_info_packet vendor_info_packet;
-+ /* Source Product Description */
-+ struct hw_info_packet spd_packet;
-+ /* Video Stream Configuration */
-+ struct hw_info_packet vsc_packet;
-+};
-+
-+
-+enum channel_command_type {
-+ CHANNEL_COMMAND_I2C,
-+ CHANNEL_COMMAND_I2C_OVER_AUX,
-+ CHANNEL_COMMAND_AUX
-+};
-+
-+
-+/* maximum TMDS transmitter pixel clock is 165 MHz. So it is KHz */
-+#define TMDS_MAX_PIXEL_CLOCK_IN_KHZ 165000
-+#define NATIVE_HDMI_MAX_PIXEL_CLOCK_IN_KHZ 297000
-+
-+struct hw_adjustment_range {
-+ int32_t hw_default;
-+ int32_t min;
-+ int32_t max;
-+ int32_t step;
-+ uint32_t divider; /* (actually HW range is min/divider; divider !=0) */
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/i2caux_interface.h b/drivers/gpu/drm/amd/dal/include/i2caux_interface.h
-new file mode 100644
-index 0000000..b961d24
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/i2caux_interface.h
-@@ -0,0 +1,127 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_I2CAUX_INTERFACE_H__
-+#define __DAL_I2CAUX_INTERFACE_H__
-+
-+#include "ddc_interface.h"
-+#include "adapter_service_interface.h"
-+
-+struct i2c_payload {
-+ bool write;
-+ uint8_t address;
-+ uint8_t length;
-+ uint8_t *data;
-+};
-+
-+enum i2c_command_engine {
-+ I2C_COMMAND_ENGINE_DEFAULT,
-+ I2C_COMMAND_ENGINE_SW,
-+ I2C_COMMAND_ENGINE_HW
-+};
-+
-+struct i2c_command {
-+ struct i2c_payload *payloads;
-+ uint8_t number_of_payloads;
-+
-+ enum i2c_command_engine engine;
-+
-+ /* expressed in KHz
-+ * zero means "use default value" */
-+ uint32_t speed;
-+};
-+
-+#define DEFAULT_AUX_MAX_DATA_SIZE 16
-+#define AUX_MAX_DEFER_WRITE_RETRY 20
-+
-+struct aux_payload {
-+ /* set following flag to read/write I2C data,
-+ * reset it to read/write DPCD data */
-+ bool i2c_over_aux;
-+ /* set following flag to write data,
-+ * reset it to read data */
-+ bool write;
-+ uint32_t address;
-+ uint8_t length;
-+ uint8_t *data;
-+};
-+
-+struct aux_command {
-+ struct aux_payload *payloads;
-+ uint8_t number_of_payloads;
-+
-+ /* expressed in milliseconds
-+ * zero means "use default value" */
-+ uint32_t defer_delay;
-+
-+ /* zero means "use default value" */
-+ uint32_t max_defer_write_retry;
-+};
-+
-+union aux_config {
-+ struct {
-+ uint32_t ALLOW_AUX_WHEN_HPD_LOW:1;
-+ } bits;
-+ uint32_t raw;
-+};
-+
-+struct i2caux;
-+
-+struct i2caux *dal_i2caux_create(
-+ struct adapter_service *as,
-+ struct dc_context *ctx);
-+
-+bool dal_i2caux_submit_i2c_command(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc,
-+ struct i2c_command *cmd);
-+
-+bool dal_i2caux_submit_aux_command(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc,
-+ struct aux_command *cmd);
-+
-+void dal_i2caux_keep_engine_power_up(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc,
-+ bool keep_power_up);
-+
-+bool dal_i2caux_start_gtc_sync(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc);
-+
-+bool dal_i2caux_stop_gtc_sync(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc);
-+
-+void dal_i2caux_configure_aux(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc,
-+ union aux_config cfg);
-+
-+void dal_i2caux_destroy(
-+ struct i2caux **ptr);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/irq_interface.h b/drivers/gpu/drm/amd/dal/include/irq_interface.h
-new file mode 100644
-index 0000000..0faa48f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/irq_interface.h
-@@ -0,0 +1,53 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_IRQ_INTERFACE_H__
-+#define __DAL_IRQ_INTERFACE_H__
-+
-+#include "gpio_types.h"
-+
-+struct irq;
-+
-+enum gpio_result dal_irq_open(
-+ struct irq *irq);
-+
-+enum gpio_result dal_irq_get_value(
-+ const struct irq *irq,
-+ uint32_t *value);
-+
-+enum dc_irq_source dal_irq_get_source(
-+ const struct irq *irq);
-+
-+enum dc_irq_source dal_irq_get_rx_source(
-+ const struct irq *irq);
-+
-+enum gpio_result dal_irq_setup_hpd_filter(
-+ struct irq *irq,
-+ struct gpio_hpd_config *config);
-+
-+void dal_irq_close(
-+ struct irq *irq);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/irq_service_interface.h b/drivers/gpu/drm/amd/dal/include/irq_service_interface.h
-new file mode 100644
-index 0000000..7ae4aeb
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/irq_service_interface.h
-@@ -0,0 +1,55 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_IRQ_SERVICE_INTERFACE_H__
-+#define __DAL_IRQ_SERVICE_INTERFACE_H__
-+
-+#include "include/adapter_service_types.h"
-+
-+struct irq_service_init_data {
-+ struct dc_context *ctx;
-+};
-+
-+struct irq_service *dal_irq_service_create(
-+ enum dce_version version,
-+ struct irq_service_init_data *init_data);
-+
-+void dal_irq_service_destroy(struct irq_service **irq_service);
-+
-+bool dal_irq_service_set(
-+ struct irq_service *irq_service,
-+ enum dc_irq_source source,
-+ bool enable);
-+
-+bool dal_irq_service_ack(
-+ struct irq_service *irq_service,
-+ enum dc_irq_source source);
-+
-+enum dc_irq_source dal_irq_service_to_irq_source(
-+ struct irq_service *irq_service,
-+ uint32_t src_id,
-+ uint32_t ext_id);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/isr_config_types.h b/drivers/gpu/drm/amd/dal/include/isr_config_types.h
-new file mode 100644
-index 0000000..2e822f0
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/isr_config_types.h
-@@ -0,0 +1,157 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_ISR_TYPES_H__
-+#define __DAL_ISR_TYPES_H__
-+
-+#include "grph_object_id.h"
-+#include "dc_types.h"
-+
-+struct plane_config;
-+enum {
-+ /*move to common*/
-+ MAX_COFUNC_PATH_COMMON = 6,
-+ /*CZ worst case*/
-+ MAX_NUM_PLANES = 4
-+};
-+
-+enum plane_type {
-+ PLANE_TYPE_GRPH = 0,
-+ PLANE_TYPE_VIDEO
-+};
-+
-+struct plane_id {
-+ enum plane_type select;
-+ enum controller_id controller_id;
-+};
-+
-+union display_plane_mask {
-+ struct {
-+ uint32_t CLONE_PRIMARY_CONTROLLER_ID_SET:1;
-+ uint32_t INTERLEAVED_CONTROLLER_ID_SET:1;
-+ uint32_t RESERVED:30;
-+ } bits;
-+ uint32_t value;
-+};
-+
-+struct display_plane_format {
-+ /* always valid */
-+ union display_plane_mask mask;
-+ /* always valid */
-+ uint32_t display_index;
-+ /* always valid */
-+ enum dc_timing_3d_format format;
-+ /* always valid */
-+ enum controller_id controller_id;
-+ /* valid only if CLONE_PRIMARY_CONTROLLER_ID_SET on */
-+ enum controller_id clone_primary_controller_id;
-+ /* valid only if stereo interleave mode is on */
-+ enum controller_id interleave_controller_id;
-+ /* valid only if crtc stereo is on */
-+ uint32_t right_eye_3d_polarity:1;
-+};
-+
-+struct display_plane_set {
-+ struct display_plane_format
-+ set_mode_formats[MAX_COFUNC_PATH_COMMON];
-+ uint32_t reset_mode_index[
-+ MAX_COFUNC_PATH_COMMON];
-+ uint32_t num_set_mode_formats;
-+ uint32_t num_reset_mode_index;
-+};
-+
-+enum layers_setup {
-+ LAYERS_SETUP_NOTHING = 0,
-+ LAYERS_SETUP_SET,
-+ LAYERS_SETUP_FREE
-+};
-+
-+union plane_cfg_internal_flags {
-+ struct {
-+ uint32_t PLANE_OWNS_CRTC:1;
-+ uint32_t RESERVED:31;
-+ } bits;
-+ uint32_t value;
-+};
-+
-+
-+struct plane_cfg_internal {
-+ const struct plane_config *config;
-+ enum layers_setup setup;
-+ union plane_cfg_internal_flags flags;
-+};
-+
-+enum lock_type {
-+ LOCK_TYPE_GRPH = 0,
-+ LOCK_TYPE_SURF,
-+ LOCK_TYPE_SCL,
-+ LOCK_TYPE_BLND,
-+ /* lock the given pipe with options above */
-+ LOCK_TYPE_THIS
-+};
-+
-+enum alpha_mode {
-+ ALPHA_MODE_PIXEL = 0,
-+ ALPHA_MODE_PIXEL_AND_GLOBAL = 1,
-+ ALPHA_MODE_GLOBAL = 2
-+};
-+
-+union alpha_mode_cfg_flag {
-+ struct {
-+ uint32_t MODE_IS_SET:1;
-+ uint32_t MODE_MULTIPLIED_IS_SET:1;
-+ uint32_t GLOBAL_ALPHA_IS_SET:1;
-+ uint32_t GLOBAL_ALPHA_GAIN_IS_SET:1;
-+
-+ uint32_t MULTIPLIED_MODE:1;
-+ uint32_t GLOBAL_ALPHA:8;
-+ /* total 21 bits! */
-+ uint32_t GLOBAL_ALPHA_GAIN:8;
-+ } bits;
-+ uint32_t value;
-+};
-+
-+struct alpha_mode_cfg {
-+ union alpha_mode_cfg_flag flags;
-+ enum alpha_mode mode;
-+};
-+
-+union pending_cfg_changes {
-+ struct {
-+ uint32_t SCL_UNLOCK_REQUIRED:1;
-+ uint32_t BLND_UNLOCK_REQUIRED:1;
-+ uint32_t INPUT_CSC_SWITCH_REQUIRED:1;
-+ uint32_t OUTPUT_CSC_SWITCH_REQUIRED:1;
-+ } bits;
-+ uint32_t value;
-+};
-+
-+struct pending_plane_changes {
-+ union pending_cfg_changes changes;
-+ struct plane_id id;
-+};
-+
-+
-+#endif /* __DAL_ISR_TYPES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/link_encoder_types.h b/drivers/gpu/drm/amd/dal/include/link_encoder_types.h
-new file mode 100644
-index 0000000..2a59902
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/link_encoder_types.h
-@@ -0,0 +1,32 @@
-+/*
-+ * link_encoder_types.h
-+ *
-+ * Created on: Oct 6, 2015
-+ * Author: yonsun
-+ */
-+
-+#ifndef DRIVERS_GPU_DRM_AMD_DAL_DEV_INCLUDE_LINK_ENCODER_TYPES_H_
-+#define DRIVERS_GPU_DRM_AMD_DAL_DEV_INCLUDE_LINK_ENCODER_TYPES_H_
-+
-+#include "encoder_interface.h"
-+
-+struct link_enc_status {
-+ int dummy; /*TODO*/
-+};
-+struct link_encoder {
-+ struct adapter_service *adapter_service;
-+ int32_t be_engine_offset;
-+ int32_t aux_channel_offset;
-+ int32_t transmitter_offset;
-+ struct dc_context *ctx;
-+ struct graphics_object_id id;
-+ struct graphics_object_id connector;
-+ uint32_t input_signals;
-+ uint32_t output_signals;
-+ enum engine_id preferred_engine;
-+ struct encoder_feature_support features;
-+ enum transmitter transmitter;
-+ enum hpd_source_id hpd_source;
-+};
-+
-+#endif /* DRIVERS_GPU_DRM_AMD_DAL_DEV_INCLUDE_LINK_ENCODER_TYPES_H_ */
-diff --git a/drivers/gpu/drm/amd/dal/include/link_service_interface.h b/drivers/gpu/drm/amd/dal/include/link_service_interface.h
-new file mode 100644
-index 0000000..2ac9311
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/link_service_interface.h
-@@ -0,0 +1,202 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_LINK_SERVICE_INTERFACE_H__
-+#define __DAL_LINK_SERVICE_INTERFACE_H__
-+
-+#include "include/link_service_types.h"
-+
-+/* forward declaration */
-+struct link_service;
-+struct hw_crtc_timing;
-+struct hw_path_mode;
-+struct display_path;
-+struct hw_path_mode_set;
-+struct link_training_preference;
-+enum ddc_result;
-+
-+struct link_service *dal_link_service_create(
-+ struct link_service_init_data *init_data);
-+
-+void dal_link_service_destroy(
-+ struct link_service **ls);
-+
-+enum link_service_type dal_ls_get_link_service_type(
-+ struct link_service *link_service);
-+
-+bool dal_ls_validate_mode_timing(
-+ struct link_service *ls,
-+ uint32_t display_index,
-+ const struct hw_crtc_timing *timing,
-+ struct link_validation_flags flags);
-+
-+bool dal_ls_get_mst_sink_info(
-+ struct link_service *ls,
-+ uint32_t display_index,
-+ struct mst_sink_info *sink_info);
-+
-+bool dal_ls_get_gtc_sync_status(
-+ struct link_service *ls);
-+
-+bool dal_ls_enable_stream(
-+ struct link_service *ls,
-+ uint32_t display_index,
-+ struct hw_path_mode *path_mode);
-+
-+bool dal_ls_disable_stream(
-+ struct link_service *ls,
-+ uint32_t display_index,
-+ struct hw_path_mode *poath_mode);
-+
-+bool dal_ls_optimized_enable_stream(
-+ struct link_service *ls,
-+ uint32_t display_index,
-+ struct display_path *display_path);
-+
-+void dal_ls_update_stream_features(
-+ struct link_service *ls,
-+ const struct hw_path_mode *path_mode);
-+
-+bool dal_ls_blank_stream(
-+ struct link_service *ls,
-+ uint32_t display_index,
-+ struct hw_path_mode *path_mode);
-+
-+bool dal_ls_unblank_stream(
-+ struct link_service *ls,
-+ uint32_t display_index,
-+ struct hw_path_mode *path_mode);
-+
-+bool dal_ls_pre_mode_change(
-+ struct link_service *ls,
-+ uint32_t display_index,
-+ struct hw_path_mode *path_mode);
-+
-+bool dal_ls_post_mode_change(
-+ struct link_service *ls,
-+ uint32_t display_index,
-+ struct hw_path_mode *path_mode);
-+
-+bool dal_ls_power_on_stream(
-+ struct link_service *ls,
-+ uint32_t display_index,
-+ struct hw_path_mode *path_mode);
-+
-+bool dal_ls_power_off_stream(
-+ struct link_service *ls,
-+ uint32_t display_index,
-+ struct hw_path_mode *path_mode);
-+
-+void dal_ls_retrain_link(
-+ struct link_service *ls,
-+ struct hw_path_mode_set *path_set);
-+
-+bool dal_ls_get_current_link_setting(
-+ struct link_service *ls,
-+ struct link_settings *link_settings);
-+
-+void dal_ls_connect_link(
-+ struct link_service *ls,
-+ const struct display_path *display_path,
-+ bool initial_detection);
-+
-+void dal_ls_disconnect_link(
-+ struct link_service *ls);
-+
-+bool dal_ls_is_mst_network_present(
-+ struct link_service *ls);
-+
-+void dal_ls_invalidate_down_stream_devices(
-+ struct link_service *ls);
-+
-+bool dal_ls_are_mst_displays_cofunctional(
-+ struct link_service *ls,
-+ const uint32_t *array_display_index,
-+ uint32_t len);
-+
-+bool dal_ls_is_sink_present_at_display_index(
-+ struct link_service *ls,
-+ uint32_t display_index);
-+
-+struct ddc_service *dal_ls_obtain_mst_ddc_service(
-+ struct link_service *ls,
-+ uint32_t display_index);
-+
-+void dal_ls_release_mst_ddc_service(
-+ struct link_service *ls,
-+ struct ddc_service *ddc_service);
-+
-+void dal_ls_release_hw(
-+ struct link_service *ls);
-+
-+bool dal_ls_associate_link(
-+ struct link_service *ls,
-+ uint32_t display_index,
-+ uint32_t link_index,
-+ bool is_internal_link);
-+
-+bool dal_dpsst_ls_set_overridden_trained_link_settings(
-+ struct link_service *ls,
-+ const struct link_settings *link_settings);
-+
-+void dal_dpsst_ls_set_link_training_preference(
-+ struct link_service *ls,
-+ const struct link_training_preference *ltp);
-+
-+struct link_training_preference
-+ dal_dpsst_ls_get_link_training_preference(
-+ struct link_service *ls);
-+
-+bool dal_ls_should_send_notification(
-+ struct link_service *ls);
-+
-+uint32_t dal_ls_get_notification_display_index(
-+ struct link_service *ls);
-+
-+enum ddc_result dal_dpsst_ls_read_dpcd_data(
-+ struct link_service *ls,
-+ uint32_t address,
-+ uint8_t *data,
-+ uint32_t size);
-+
-+enum ddc_result dal_dpsst_ls_write_dpcd_data(
-+ struct link_service *ls,
-+ uint32_t address,
-+ const uint8_t *data,
-+ uint32_t size);
-+
-+bool dal_ls_is_link_psr_supported(struct link_service *ls);
-+
-+bool dal_ls_is_stream_drr_supported(struct link_service *ls);
-+
-+void dal_ls_set_link_psr_capabilities(
-+ struct link_service *ls,
-+ struct psr_caps *psr_caps);
-+
-+void dal_ls_get_link_psr_capabilities(
-+ struct link_service *ls,
-+ struct psr_caps *psr_caps);
-+
-+#endif /* __DAL_LINK_SERVICE_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/link_service_types.h b/drivers/gpu/drm/amd/dal/include/link_service_types.h
-new file mode 100644
-index 0000000..0df5687
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/link_service_types.h
-@@ -0,0 +1,428 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_LINK_SERVICE_TYPES_H__
-+#define __DAL_LINK_SERVICE_TYPES_H__
-+
-+#include "dal_services_types.h"
-+
-+#include "grph_object_id.h"
-+#include "dpcd_defs.h"
-+#include "dal_types.h"
-+#include "irq_types.h"
-+
-+/*struct mst_mgr_callback_object;*/
-+struct ddc;
-+struct irq_manager;
-+
-+enum link_service_type {
-+ LINK_SERVICE_TYPE_LEGACY = 0,
-+ LINK_SERVICE_TYPE_DP_SST,
-+ LINK_SERVICE_TYPE_DP_MST,
-+ LINK_SERVICE_TYPE_MAX
-+};
-+
-+struct link_validation_flags {
-+ uint32_t DYNAMIC_VALIDATION:1;
-+ uint32_t CANDIDATE_TIMING:1;
-+ uint32_t START_OF_VALIDATION:1;
-+};
-+
-+/* Post Cursor 2 is optional for transmitter
-+ * and it applies only to the main link operating at HBR2
-+ */
-+enum post_cursor2 {
-+ POST_CURSOR2_DISABLED = 0, /* direct HW translation! */
-+ POST_CURSOR2_LEVEL1,
-+ POST_CURSOR2_LEVEL2,
-+ POST_CURSOR2_LEVEL3,
-+ POST_CURSOR2_MAX_LEVEL = POST_CURSOR2_LEVEL3,
-+};
-+
-+enum voltage_swing {
-+ VOLTAGE_SWING_LEVEL0 = 0, /* direct HW translation! */
-+ VOLTAGE_SWING_LEVEL1,
-+ VOLTAGE_SWING_LEVEL2,
-+ VOLTAGE_SWING_LEVEL3,
-+ VOLTAGE_SWING_MAX_LEVEL = VOLTAGE_SWING_LEVEL3
-+};
-+
-+enum pre_emphasis {
-+ PRE_EMPHASIS_DISABLED = 0, /* direct HW translation! */
-+ PRE_EMPHASIS_LEVEL1,
-+ PRE_EMPHASIS_LEVEL2,
-+ PRE_EMPHASIS_LEVEL3,
-+ PRE_EMPHASIS_MAX_LEVEL = PRE_EMPHASIS_LEVEL3
-+};
-+
-+enum dpcd_value_mask {
-+ DPCD_VALUE_MASK_MAX_LANE_COUNT_LANE_COUNT = 0x1F,
-+ DPCD_VALUE_MASK_MAX_LANE_COUNT_TPS3_SUPPORTED = 0x40,
-+ DPCD_VALUE_MASK_MAX_LANE_COUNT_ENHANCED_FRAME_EN = 0x80,
-+ DPCD_VALUE_MASK_MAX_DOWNSPREAD = 0x01,
-+ DPCD_VALUE_MASK_LANE_ALIGN_STATUS_INTERLANE_ALIGN_DONE = 0x01
-+};
-+
-+enum dp_power_state {
-+ DP_POWER_STATE_D0 = 1,
-+ DP_POWER_STATE_D3
-+};
-+
-+enum dpcd_downstream_port_types {
-+ DPCD_DOWNSTREAM_DP,
-+ DPCD_DOWNSTREAM_VGA,
-+ DPCD_DOWNSTREAM_DVI_HDMI,
-+ /* has no EDID (TV, CV) */
-+ DPCD_DOWNSTREAM_NON_DDC
-+};
-+
-+enum edp_revision {
-+ /* eDP version 1.1 or lower */
-+ EDP_REVISION_11 = 0x00,
-+ /* eDP version 1.2 */
-+ EDP_REVISION_12 = 0x01,
-+ /* eDP version 1.3 */
-+ EDP_REVISION_13 = 0x02
-+};
-+
-+enum lane_count {
-+ LANE_COUNT_UNKNOWN = 0,
-+ LANE_COUNT_ONE = 1,
-+ LANE_COUNT_TWO = 2,
-+ LANE_COUNT_FOUR = 4,
-+ LANE_COUNT_EIGHT = 8,
-+ LANE_COUNT_DP_MAX = LANE_COUNT_FOUR
-+};
-+
-+/* This is actually a reference clock (27MHz) multiplier
-+ * 162MBps bandwidth for 1.62GHz like rate,
-+ * 270MBps for 2.70GHz,
-+ * 324MBps for 3.24Ghz,
-+ * 540MBps for 5.40GHz
-+ */
-+enum link_rate {
-+ LINK_RATE_UNKNOWN = 0,
-+ LINK_RATE_LOW = 0x06,
-+ LINK_RATE_HIGH = 0x0A,
-+ LINK_RATE_RBR2 = 0x0C,
-+ LINK_RATE_HIGH2 = 0x14
-+};
-+
-+enum {
-+ LINK_RATE_REF_FREQ_IN_KHZ = 27000 /*27MHz*/
-+};
-+
-+enum link_spread {
-+ LINK_SPREAD_DISABLED = 0x00,
-+ /* 0.5 % downspread 30 kHz */
-+ LINK_SPREAD_05_DOWNSPREAD_30KHZ = 0x10,
-+ /* 0.5 % downspread 33 kHz */
-+ LINK_SPREAD_05_DOWNSPREAD_33KHZ = 0x11
-+};
-+
-+/* DPCD_ADDR_DOWNSTREAM_PORT_PRESENT register value */
-+union dpcd_downstream_port {
-+ struct {
-+#if defined(LITTLEENDIAN_CPU)
-+ uint8_t PRESENT:1;
-+ uint8_t TYPE:2;
-+ uint8_t FORMAT_CONV:1;
-+ uint8_t RESERVED:4;
-+#elif defined(BIGENDIAN_CPU)
-+ uint8_t RESERVED:4;
-+ uint8_t FORMAT_CONV:1;
-+ uint8_t TYPE:2;
-+ uint8_t PRESENT:1;
-+#else
-+ #error ARCH not defined!
-+#endif
-+ } bits;
-+
-+ uint8_t raw;
-+};
-+
-+/* DPCD_ADDR_SINK_COUNT register value */
-+union dpcd_sink_count {
-+ struct {
-+#if defined(LITTLEENDIAN_CPU)
-+ uint8_t SINK_COUNT:6;
-+ uint8_t CP_READY:1;
-+ uint8_t RESERVED:1;
-+#elif defined(BIGENDIAN_CPU)
-+ uint8_t RESERVED:1;
-+ uint8_t CP_READY:1;
-+ uint8_t SINK_COUNT:6;
-+#else
-+ #error ARCH not defined!
-+#endif
-+ } bits;
-+
-+ uint8_t raw;
-+};
-+
-+struct link_settings {
-+ enum lane_count lane_count;
-+ enum link_rate link_rate;
-+ enum link_spread link_spread;
-+};
-+
-+struct lane_settings {
-+ enum voltage_swing VOLTAGE_SWING;
-+ enum pre_emphasis PRE_EMPHASIS;
-+ enum post_cursor2 POST_CURSOR2;
-+};
-+
-+struct link_training_settings {
-+ struct link_settings link_settings;
-+ struct lane_settings lane_settings[LANE_COUNT_DP_MAX];
-+ bool allow_invalid_msa_timing_param;
-+};
-+
-+enum hw_dp_training_pattern {
-+ HW_DP_TRAINING_PATTERN_1 = 0,
-+ HW_DP_TRAINING_PATTERN_2,
-+ HW_DP_TRAINING_PATTERN_3
-+};
-+
-+/*TODO: Move this enum test harness*/
-+/* Test patterns*/
-+enum dp_test_pattern {
-+ /* Input data is pass through Scrambler
-+ * and 8b10b Encoder straight to output*/
-+ DP_TEST_PATTERN_VIDEO_MODE = 0,
-+ /* phy test patterns*/
-+ DP_TEST_PATTERN_D102,
-+ DP_TEST_PATTERN_SYMBOL_ERROR,
-+ DP_TEST_PATTERN_PRBS7,
-+
-+ DP_TEST_PATTERN_80BIT_CUSTOM,
-+ DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE,
-+
-+ /* Link Training Patterns */
-+ DP_TEST_PATTERN_TRAINING_PATTERN1,
-+ DP_TEST_PATTERN_TRAINING_PATTERN2,
-+ DP_TEST_PATTERN_TRAINING_PATTERN3,
-+
-+ /* link test patterns*/
-+ DP_TEST_PATTERN_COLOR_SQUARES,
-+ DP_TEST_PATTERN_COLOR_SQUARES_CEA,
-+ DP_TEST_PATTERN_VERTICAL_BARS,
-+ DP_TEST_PATTERN_HORIZONTAL_BARS,
-+ DP_TEST_PATTERN_COLOR_RAMP,
-+
-+ /* audio test patterns*/
-+ DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED,
-+ DP_TEST_PATTERN_AUDIO_SAWTOOTH,
-+
-+ DP_TEST_PATTERN_UNSUPPORTED
-+};
-+
-+enum dp_panel_mode {
-+ /* not required */
-+ DP_PANEL_MODE_DEFAULT,
-+ /* standard mode for eDP */
-+ DP_PANEL_MODE_EDP,
-+ /* external chips specific settings */
-+ DP_PANEL_MODE_SPECIAL
-+};
-+
-+/**
-+ * @brief LinkServiceInitOptions to set certain bits
-+ */
-+struct link_service_init_options {
-+ uint32_t APPLY_MISALIGNMENT_BUG_WORKAROUND:1;
-+};
-+
-+/**
-+ * @brief data required to initialize LinkService
-+ */
-+struct link_service_init_data {
-+ /* number of displays indices which the MST Mgr would manange*/
-+ uint32_t num_of_displays;
-+ enum link_service_type link_type;
-+ /*struct mst_mgr_callback_object*topology_change_callback;*/
-+ /* native aux access */
-+ struct ddc_service *dpcd_access_srv;
-+ /* for calling HWSS to program HW */
-+ struct hw_sequencer *hwss;
-+ /* the source which to register IRQ on */
-+ enum dc_irq_source irq_src_hpd_rx;
-+ enum dc_irq_source irq_src_dp_sink;
-+ /* other init options such as SW Workarounds */
-+ struct link_service_init_options init_options;
-+ uint32_t connector_enum_id;
-+ struct graphics_object_id connector_id;
-+ struct adapter_service *adapter_service;
-+ struct dc_context *ctx;
-+ struct topology_mgr *tm;
-+};
-+
-+/**
-+ * @brief LinkServiceInitOptions to set certain bits
-+ */
-+struct LinkServiceInitOptions {
-+ uint32_t APPLY_MISALIGNMENT_BUG_WORKAROUND:1;
-+};
-+
-+/* DPCD_ADDR_TRAINING_LANEx_SET registers value */
-+union dpcd_training_lane_set {
-+ struct {
-+#if defined(LITTLEENDIAN_CPU)
-+ uint8_t VOLTAGE_SWING_SET:2;
-+ uint8_t MAX_SWING_REACHED:1;
-+ uint8_t PRE_EMPHASIS_SET:2;
-+ uint8_t MAX_PRE_EMPHASIS_REACHED:1;
-+ /* following is reserved in DP 1.1 */
-+ uint8_t POST_CURSOR2_SET:2;
-+#elif defined(BIGENDIAN_CPU)
-+ uint8_t POST_CURSOR2_SET:2;
-+ uint8_t MAX_PRE_EMPHASIS_REACHED:1;
-+ uint8_t PRE_EMPHASIS_SET:2;
-+ uint8_t MAX_SWING_REACHED:1;
-+ uint8_t VOLTAGE_SWING_SET:2;
-+#else
-+ #error ARCH not defined!
-+#endif
-+ } bits;
-+
-+ uint8_t raw;
-+};
-+
-+/* DPCD_ADDR_TRAINING_LANEx_SET2 registers value - since DP 1.2 */
-+union dpcd_training_lanes_set2 {
-+ struct {
-+#if defined(LITTLEENDIAN_CPU)
-+ uint8_t LANE0_POST_CURSOR2_SET:2;
-+ uint8_t LANE0_MAX_POST_CURSOR2_REACHED:1;
-+ uint8_t LANE0_RESERVED:1;
-+ uint8_t LANE1_POST_CURSOR2_SET:2;
-+ uint8_t LANE1_MAX_POST_CURSOR2_REACHED:1;
-+ uint8_t LANE1_RESERVED:1;
-+#elif defined(BIGENDIAN_CPU)
-+ uint8_t LANE1_RESERVED:1;
-+ uint8_t LANE1_MAX_POST_CURSOR2_REACHED:1;
-+ uint8_t LANE1_POST_CURSOR2_SET:2;
-+ uint8_t LANE0_RESERVED:1;
-+ uint8_t LANE0_MAX_POST_CURSOR2_REACHED:1;
-+ uint8_t LANE0_POST_CURSOR2_SET:2;
-+#else
-+ #error ARCH not defined!
-+#endif
-+ } bits;
-+
-+ uint8_t raw;
-+};
-+
-+/**
-+ * @brief represent the 16 byte
-+ * global unique identifier
-+ */
-+struct mst_guid {
-+ uint8_t ids[16];
-+};
-+
-+/**
-+ * @brief represents the relative address used
-+ * to identify a node in MST topology network
-+ */
-+struct mst_rad {
-+ /* number of links. rad[0] up to
-+ * rad [linkCount - 1] are valid. */
-+ uint32_t rad_link_count;
-+ /* relative address. rad[0] is the
-+ * first device connected to the source. */
-+ uint8_t rad[15];
-+ /* extra 10 bytes for underscores; for e.g.:2_1_8*/
-+ int8_t rad_str[25];
-+};
-+
-+/**
-+ * @brief this structure is used to report
-+ * properties associated to a sink device
-+ */
-+struct mst_sink_info {
-+ /* global unique identifier */
-+ struct mst_guid guid;
-+ /* relative address */
-+ struct mst_rad rad;
-+ /* total bandwidth available on the DP connector */
-+ uint32_t total_available_bandwidth_in_mbps;
-+ /* bandwidth allocated to the sink device. */
-+ uint32_t allocated_bandwidth_in_mbps;
-+ /* bandwidth consumed to support for the current mode. */
-+ uint32_t consumed_bandwidth_in_mbps;
-+};
-+
-+/**
-+ * @brief represent device information in MST topology
-+ */
-+struct mst_device_info {
-+ /* global unique identifier*/
-+ struct mst_guid guid;
-+ /* relative address*/
-+ struct mst_rad rad;
-+};
-+
-+/* DP MST stream allocation (payload bandwidth number) */
-+struct dp_mst_stream_allocation {
-+ /* stream engine id (DIG) */
-+ enum engine_id engine;
-+ /* number of slots required for the DP stream in
-+ * transport packet */
-+ uint32_t slot_count;
-+ uint32_t pbn;
-+ uint32_t pbn_per_slot;
-+};
-+
-+/* DP MST stream allocation table */
-+struct dp_mst_stream_allocation_table {
-+ /* number of DP video streams */
-+ uint32_t stream_count;
-+ /* array of stream allocations */
-+ struct dp_mst_stream_allocation stream_allocations[1];
-+};
-+
-+struct dp_test_event_data {
-+ /*size of parameters (starting from params) in bytes*/
-+ uint32_t size;
-+ /*parameters block*/
-+ uint32_t params[1];
-+};
-+
-+struct psr_caps {
-+ /* These parameters are from PSR capabilities reported by Sink DPCD. */
-+ uint8_t psr_version;
-+ uint32_t psr_rfb_setup_time;
-+ bool psr_exit_link_training_req;
-+
-+ /* These parameters are calculated in Driver, based on display timing
-+ * and Sink capabilities.
-+ * If VBLANK region is too small and Sink takes a long time to power up
-+ * Remote Frame Buffer, it may take an extra frame to enter PSR */
-+ bool psr_frame_capture_indication_req;
-+ uint32_t psr_sdp_transmit_line_num_deadline;
-+};
-+
-+#endif /*__DAL_LINK_SERVICE_TYPES_H__*/
-diff --git a/drivers/gpu/drm/amd/dal/include/logger_interface.h b/drivers/gpu/drm/amd/dal/include/logger_interface.h
-new file mode 100644
-index 0000000..4d945ea
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/logger_interface.h
-@@ -0,0 +1,153 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_LOGGER_INTERFACE_H__
-+#define __DAL_LOGGER_INTERFACE_H__
-+
-+#include "logger_types.h"
-+
-+struct dal_logger;
-+struct dc_context;
-+union logger_flags;
-+
-+/*
-+ * TODO: This logger functionality needs to be implemented and reworked.
-+ */
-+
-+
-+/*
-+ *
-+ * DAL logger functionality
-+ *
-+ */
-+
-+struct dal_logger *dal_logger_create(struct dc_context *ctx);
-+
-+uint32_t dal_logger_destroy(struct dal_logger **logger);
-+
-+uint32_t dal_logger_get_mask(
-+ struct dal_logger *logger,
-+ enum log_major lvl_major, enum log_minor lvl_minor);
-+
-+uint32_t dal_logger_set_mask(
-+ struct dal_logger *logger,
-+ enum log_major lvl_major, enum log_minor lvl_minor);
-+
-+uint32_t dal_logger_get_masks(
-+ struct dal_logger *logger,
-+ enum log_major lvl_major);
-+
-+void dal_logger_set_masks(
-+ struct dal_logger *logger,
-+ enum log_major lvl_major, uint32_t log_mask);
-+
-+uint32_t dal_logger_unset_mask(
-+ struct dal_logger *logger,
-+ enum log_major lvl_major, enum log_minor lvl_minor);
-+
-+bool dal_logger_should_log(
-+ struct dal_logger *logger,
-+ enum log_major major,
-+ enum log_minor minor);
-+
-+uint32_t dal_logger_get_flags(
-+ struct dal_logger *logger);
-+
-+void dal_logger_set_flags(
-+ struct dal_logger *logger,
-+ union logger_flags flags);
-+
-+void dal_logger_write(
-+ struct dal_logger *logger,
-+ enum log_major major,
-+ enum log_minor minor,
-+ const char *msg,
-+ ...);
-+
-+void dal_logger_append(
-+ struct log_entry *entry,
-+ const char *msg,
-+ ...);
-+
-+uint32_t dal_logger_read(
-+ struct dal_logger *logger,
-+ uint32_t output_buffer_size,
-+ char *output_buffer,
-+ uint32_t *bytes_read,
-+ bool single_line);
-+
-+void dal_logger_open(
-+ struct dal_logger *logger,
-+ struct log_entry *entry,
-+ enum log_major major,
-+ enum log_minor minor);
-+
-+void dal_logger_close(struct log_entry *entry);
-+
-+uint32_t dal_logger_get_buffer_size(struct dal_logger *logger);
-+
-+uint32_t dal_logger_set_buffer_size(
-+ struct dal_logger *logger,
-+ uint32_t new_size);
-+
-+const struct log_major_info *dal_logger_enum_log_major_info(
-+ struct dal_logger *logger,
-+ unsigned int enum_index);
-+
-+const struct log_minor_info *dal_logger_enum_log_minor_info(
-+ struct dal_logger *logger,
-+ enum log_major major,
-+ unsigned int enum_index);
-+
-+/* Any function which is empty or have incomplete implementation should be
-+ * marked by this macro.
-+ * Note that the message will be printed exactly once for every function
-+ * it is used in order to avoid repeating of the same message. */
-+#define DAL_LOGGER_NOT_IMPL(log_minor, fmt, ...) \
-+{ \
-+ static bool print_not_impl = true; \
-+\
-+ if (print_not_impl == true) { \
-+ print_not_impl = false; \
-+ dal_logger_write(ctx->logger, LOG_MAJOR_WARNING, \
-+ log_minor, "DAL_NOT_IMPL: " fmt, ##__VA_ARGS__); \
-+ } \
-+}
-+
-+/******************************************************************************
-+ * Convenience macros to save on typing.
-+ *****************************************************************************/
-+
-+#define DC_ERROR(...) \
-+ dal_logger_write(dc_ctx->logger, \
-+ LOG_MAJOR_ERROR, LOG_MINOR_COMPONENT_DC, \
-+ __VA_ARGS__);
-+
-+#define DC_SYNC_INFO(...) \
-+ dal_logger_write(dc_ctx->logger, \
-+ LOG_MAJOR_SYNC, LOG_MINOR_SYNC_TIMING, \
-+ __VA_ARGS__);
-+
-+#endif /* __DAL_LOGGER_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/logger_types.h b/drivers/gpu/drm/amd/dal/include/logger_types.h
-new file mode 100644
-index 0000000..6147999
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/logger_types.h
-@@ -0,0 +1,356 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_LOGGER_TYPES_H__
-+#define __DAL_LOGGER_TYPES_H__
-+
-+
-+/*
-+ * TODO: This logger functionality needs to be implemented and reworked.
-+ */
-+
-+
-+struct dal_logger;
-+
-+enum log_major {
-+/*00*/
-+ LOG_MAJOR_ERROR = 0, /*< DAL subcomponent error MSG*/
-+/*01*/ LOG_MAJOR_WARNING, /*< DAL subcomponent warning MSG*/
-+/*02*/ LOG_MAJOR_INTERFACE_TRACE,/*< DAL subcomponent interface tracing*/
-+/*03*/ LOG_MAJOR_HW_TRACE, /*< Log ASIC register read/write,
-+ * ATOMBIOS exec table call and delays*/
-+
-+/*04*/ LOG_MAJOR_MST, /*< related to multi-stream*/
-+/*05*/ LOG_MAJOR_DCS, /*< related to Dcs*/
-+/*06*/ LOG_MAJOR_DCP, /*< related to Dcp grph and ovl,gamam and csc*/
-+/*07*/ LOG_MAJOR_BIOS, /*< related to BiosParser*/
-+/*08*/ LOG_MAJOR_REGISTER, /*< register access*/
-+/*09*/ LOG_MAJOR_INFO_PACKETS, /*< info packets*/
-+/*10*/ LOG_MAJOR_DSAT, /*< related
-+ * to Display System Analysis Tool*/
-+/*11*/ LOG_MAJOR_EC, /*< External Components - MCIL Events/queries,
-+ * PPLib notifications/queries*/
-+/*12*/ LOG_MAJOR_BWM, /*< related to Bandwidth Manager*/
-+/*13*/ LOG_MAJOR_MODE_ENUM, /*< related to mode enumeration*/
-+/*14*/ LOG_MAJOR_I2C_AUX, /*< i2c and aux channel log*/
-+/*15*/ LOG_MAJOR_LINE_BUFFER, /*< Line Buffer object logging activity*/
-+/*16*/ LOG_MAJOR_HWSS, /*< HWSS object logging activity*/
-+/*17*/ LOG_MAJOR_OPTIMIZATION, /*< Optimization code path*/
-+/*18*/ LOG_MAJOR_PERF_MEASURE, /*< Performance measurement dumps*/
-+/*19*/ LOG_MAJOR_SYNC, /*< related to HW and SW Synchronization*/
-+/*20*/ LOG_MAJOR_BACKLIGHT, /*< related to backlight */
-+/*21*/ LOG_MAJOR_INTERRUPTS, /*< logging for all interrupts */
-+
-+/*22*/ LOG_MAJOR_TM, /*< related to Topology Manager*/
-+/*23*/ LOG_MAJOR_DISPLAY_SERVICE, /*< related to Display Service*/
-+/*24*/ LOG_MAJOR_FEATURE_OVERRIDE, /*< related to features*/
-+/*25*/ LOG_MAJOR_DETECTION, /*< related to detection*/
-+ LOG_MAJOR_COUNT, /*< count of the Major categories*/
-+};
-+
-+/**
-+* @brief defines minor switch for logging. each of these define sub category
-+* of log message per LogMajor
-+*/
-+
-+
-+enum log_minor {
-+
-+ /* Special case for 'all' checkbox */
-+ LOG_MINOR_MASK_ALL = (uint32_t)-1, /* 0xFFFFFFFF */
-+/**
-+* @brief defines minor category for
-+* LOG_MAJOR_ERROR,
-+* LOG_MAJOR_WARNING,
-+* LOG_MAJOR_INTERFACE_TRACE
-+*
-+* @note each DAL subcomponent should have a corresponding enum
-+*/
-+ LOG_MINOR_COMPONENT_LINK_SERVICE = 0,
-+ LOG_MINOR_COMPONENT_DAL_INTERFACE,
-+ LOG_MINOR_COMPONENT_HWSS,
-+ LOG_MINOR_COMPONENT_ADAPTER_SERVICE,
-+ LOG_MINOR_COMPONENT_DISPLAY_SERVICE,
-+ LOG_MINOR_COMPONENT_TOPOLOGY_MANAGER,
-+ LOG_MINOR_COMPONENT_ENCODER,
-+ LOG_MINOR_COMPONENT_I2C_AUX,
-+ LOG_MINOR_COMPONENT_AUDIO,
-+ LOG_MINOR_COMPONENT_DISPLAY_CAPABILITY_SERVICE,
-+ LOG_MINOR_COMPONENT_DMCU,
-+ LOG_MINOR_COMPONENT_GPU,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ LOG_MINOR_COMPONENT_ISR,
-+ LOG_MINOR_COMPONENT_BIOS,
-+ LOG_MINOR_COMPONENT_DC,
-+ LOG_MINOR_COMPONENT_IRQ_SERVICE,
-+
-+/**
-+* @brief define minor category for LogMajor_HardwareTrace
-+*
-+* @note defines functionality based HW programming trace
-+*/
-+ LOG_MINOR_HW_TRACE_MST = 0,
-+ LOG_MINOR_HW_TRACE_TRAVIS,
-+ LOG_MINOR_HW_TRACE_HOTPLUG,
-+ LOG_MINOR_HW_TRACE_LINK_TRAINING,
-+ LOG_MINOR_HW_TRACE_SET_MODE,
-+ LOG_MINOR_HW_TRACE_RESUME_S3,
-+ LOG_MINOR_HW_TRACE_RESUME_S4,
-+ LOG_MINOR_HW_TRACE_BOOTUP,
-+ LOG_MINOR_HW_TRACE_AUDIO,
-+ LOG_MINOR_HW_TRACE_HPD_IRQ,
-+ LOG_MINOR_HW_TRACE_INTERRUPT,
-+ LOG_MINOR_HW_TRACE_MPO,
-+
-+/**
-+* @brief defines minor category for LogMajor_Mst
-+*
-+* @note define sub functionality related to MST
-+*/
-+ LOG_MINOR_MST_IRQ_HPD_RX = 0,
-+ LOG_MINOR_MST_IRQ_TIMER,
-+ LOG_MINOR_MST_NATIVE_AUX,
-+ LOG_MINOR_MST_SIDEBAND_MSG,
-+ LOG_MINOR_MST_MSG_TRANSACTION,
-+ LOG_MINOR_MST_SIDEBAND_MSG_PARSED,
-+ LOG_MINOR_MST_MSG_TRANSACTION_PARSED,
-+ LOG_MINOR_MST_AUX_MSG_DPCD_ACCESS,
-+ LOG_MINOR_MST_PROGRAMMING,
-+ LOG_MINOR_MST_TOPOLOGY_DISCOVERY,
-+ LOG_MINOR_MST_CONVERTER_CAPS,
-+
-+/**
-+* @brief defines minor category for LogMajor_DCS
-+*
-+* @note should define sub functionality related to Dcs
-+*/
-+ LOG_MINOR_DCS_EDID_EMULATOR = 0,
-+ LOG_MINOR_DCS_DONGLE_DETECTION,
-+
-+/**
-+* @brief defines minor category for DCP
-+*
-+* @note should define sub functionality related to Dcp
-+*/
-+ LOG_MINOR_DCP_GAMMA_GRPH = 0,
-+ LOG_MINOR_DCP_GAMMA_OVL,
-+ LOG_MINOR_DCP_CSC_GRPH,
-+ LOG_MINOR_DCP_CSC_OVL,
-+ LOG_MINOR_DCP_SCALER,
-+ LOG_MINOR_DCP_SCALER_TABLES,
-+/**
-+* @brief defines minor category for LogMajor_Bios
-+*
-+* @note define sub functionality related to BiosParser
-+*/
-+ LOG_MINOR_BIOS_CMD_TABLE = 0,
-+/**
-+* @brief defines minor category for LogMajor_Bios
-+*
-+* @note define sub functionality related to BiosParser
-+*/
-+ LOG_MINOR_REGISTER_INDEX = 0,
-+/**
-+* @brief defines minor category for info packets
-+*
-+*/
-+ LOG_MINOR_INFO_PACKETS_HDMI = 0,
-+
-+/**
-+* @brief defines minor category for LOG_MAJOR_DSAT
-+*
-+* @note define sub functionality related to Display System Analysis Tool
-+*/
-+ LOG_MINOR_DSAT_LOGGER = 0,
-+ LOG_MINOR_DSAT_GET_EDID,
-+ LOG_MINOR_DSAT_EDID_OVERRIDE,
-+ LOG_MINOR_DSAT_SET_ADJUSTMENTS,
-+ LOG_MINOR_DSAT_GET_ADJUSTMENTS,
-+
-+/**
-+* @brief defines minor category for LOG_MAJOR_EC
-+*
-+* @note define sub functionality related to External components notifications
-+*/
-+ LOG_MINOR_EC_PPLIB_NOTIFY = 0,
-+ LOG_MINOR_EC_PPLIB_QUERY,
-+
-+/**
-+* @brief defines minor category for LOG_MAJOR_BWM
-+*
-+* @note define sub functionality related to Bandwidth Manager
-+*/
-+ LOG_MINOR_BWM_MODE_VALIDATION = 0,
-+ LOG_MINOR_BWM_REQUIRED_BANDWIDTH_CALCS,
-+
-+/**
-+* @brief define minor category for LogMajor_ModeEnum
-+*
-+* @note defines functionality mode enumeration trace
-+*/
-+ LOG_MINOR_MODE_ENUM_BEST_VIEW_CANDIDATES = 0,
-+ LOG_MINOR_MODE_ENUM_VIEW_SOLUTION,
-+ LOG_MINOR_MODE_ENUM_TS_LIST_BUILD,
-+ LOG_MINOR_MODE_ENUM_TS_LIST,
-+ LOG_MINOR_MODE_ENUM_MASTER_VIEW_LIST,
-+ LOG_MINOR_MODE_ENUM_MASTER_VIEW_LIST_UPDATE,
-+
-+/**
-+* @brief defines minor category for LogMajor_I2C_AUX
-+*
-+* @note define sub functionality related to I2c and Aux Channel Log
-+*/
-+ LOG_MINOR_I2C_AUX_LOG = 0,
-+ LOG_MINOR_I2C_AUX_AUX_TIMESTAMP,
-+ LOG_MINOR_I2C_AUX_CFG,
-+
-+/**
-+* @brief defines minor category for LogMajor_LineBuffer
-+*
-+* @note define sub functionality related to LineBuffer
-+*/
-+ LOG_MINOR_LINE_BUFFER_POWERGATING = 0,
-+
-+/**
-+* @brief defines minor category for LogMajor_HWSS
-+*
-+* @note define sub functionality related to HWSS
-+*/
-+ LOG_MINOR_HWSS_TAPS_VALIDATION = 0,
-+
-+/**
-+* @brief defines minor category for LogMajor_Optimization
-+*
-+* @note define sub functionality related to Optimization
-+*/
-+ LOG_MINOR_OPTMZ_GENERAL = 0,
-+ LOG_MINOR_OPTMZ_DO_NOT_TURN_OFF_VCC_DURING_SET_MODE,
-+
-+/**
-+* @brief defines minor category for LogMajor_PerfMeasure
-+*
-+* @note define sub functionality related to Performance measurement dumps
-+*/
-+ LOG_MINOR_PERF_MEASURE_GENERAL = 0,
-+ LOG_MINOR_PERF_MEASURE_HEAP_MEMORY,
-+
-+/**
-+* @brief defines minor category for LogMajor_Sync
-+*
-+* @note define sub functionality related to HW and SW Synchronization
-+*/
-+ LOG_MINOR_SYNC_HW_CLOCK_ADJUST = 0,
-+ LOG_MINOR_SYNC_TIMING,
-+
-+/**
-+* @brief defines minor category for LogMajor_Backlight
-+*
-+* @note define sub functionality related to backlight (including VariBright)
-+*/
-+ LOG_MINOR_BACKLIGHT_BRIGHTESS_CAPS = 0,
-+ LOG_MINOR_BACKLIGHT_DMCU_DELTALUT,
-+ LOG_MINOR_BACKLIGHT_DMCU_BUILD_DELTALUT,
-+ LOG_MINOR_BACKLIGHT_INTERFACE,
-+ LOG_MINOR_BACKLIGHT_LID,
-+
-+/**
-+* @brief defines minor category for LOG_MAJOR_TM
-+*
-+* @note define sub functionality related to Topology Manager
-+*/
-+ LOG_MINOR_TM_INFO = 0,
-+ LOG_MINOR_TM_IFACE_TRACE,
-+ LOG_MINOR_TM_RESOURCES,
-+ LOG_MINOR_TM_ENCODER_CTL,
-+ LOG_MINOR_TM_ENG_ASN,
-+ LOG_MINOR_TM_CONTROLLER_ASN,
-+ LOG_MINOR_TM_PWR_GATING,
-+ LOG_MINOR_TM_BUILD_DSP_PATH,
-+ LOG_MINOR_TM_DISPLAY_DETECT,
-+ LOG_MINOR_TM_LINK_SRV,
-+ LOG_MINOR_TM_NOT_IMPLEMENTED,
-+ LOG_MINOR_TM_COFUNC_PATH,
-+
-+/**
-+* @brief defines minor category for LOG_MAJOR_DISPLAY_SERVICE
-+*
-+* @note define sub functionality related to Display Service
-+*/
-+ LOG_MINOR_DS_MODE_SETTING = 0,
-+
-+/**
-+* @brief defines minor category for LOG_MAJOR_FEATURE_OVERRIDE
-+*
-+* @note define sub functionality related to features in adapter service
-+*/
-+ LOG_MINOR_FEATURE_OVERRIDE = 0,
-+
-+/**
-+* @brief defines minor category for LOG_MAJOR_DETECTION
-+*
-+* @note define sub functionality related to detection
-+*/
-+ LOG_MINOR_DETECTION_EDID_PARSER = 0,
-+ LOG_MINOR_DETECTION_DP_CAPS,
-+};
-+
-+union logger_flags {
-+ struct {
-+ uint32_t ENABLE_CONSOLE:1; /* Print to console */
-+ uint32_t ENABLE_BUFFER:1; /* Print to buffer */
-+ uint32_t RESERVED:30;
-+ } bits;
-+ uint32_t value;
-+};
-+
-+struct log_entry {
-+
-+ struct dal_logger *logger;
-+ enum log_major major;
-+ enum log_minor minor;
-+
-+ char *buf;
-+ uint32_t buf_offset;
-+ uint32_t max_buf_bytes;
-+};
-+
-+/**
-+* Structure for enumerating LogMajors and LogMinors
-+*/
-+
-+#define MAX_MAJOR_NAME_LEN 32
-+#define MAX_MINOR_NAME_LEN 32
-+
-+struct log_major_info {
-+ enum log_major major;
-+ char major_name[MAX_MAJOR_NAME_LEN];
-+};
-+
-+struct log_minor_info {
-+ enum log_minor minor;
-+ char minor_name[MAX_MINOR_NAME_LEN];
-+};
-+
-+#endif /* __DAL_LOGGER_TYPES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/mode_manager_types.h b/drivers/gpu/drm/amd/dal/include/mode_manager_types.h
-new file mode 100644
-index 0000000..576b21f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/mode_manager_types.h
-@@ -0,0 +1,71 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_MODE_MANAGER_TYPES_H__
-+#define __DAL_MODE_MANAGER_TYPES_H__
-+
-+#include "bit_set.h"
-+#include "dc_types.h"
-+
-+static inline void stereo_3d_view_reset(struct stereo_3d_view *stereo_3d_view)
-+{
-+ stereo_3d_view->view_3d_format = VIEW_3D_FORMAT_NONE;
-+ stereo_3d_view->flags.raw = 0;
-+}
-+
-+bool dal_refresh_rate_is_equal(
-+ const struct refresh_rate *lhs,
-+ const struct refresh_rate *rhs);
-+
-+bool dal_refresh_rate_less_than(
-+ const struct refresh_rate *lhs,
-+ const struct refresh_rate *rhs);
-+
-+void refresh_rate_from_mode_info(
-+ struct refresh_rate *,
-+ const struct dc_mode_info *);
-+bool dal_solution_less_than(const void *lhs, const void *rhs);
-+bool dal_view_is_equal(const struct view *lhs, const struct view *rhs);
-+
-+struct pixel_format_list {
-+ uint32_t set;
-+ struct bit_set_iterator_32 iter;
-+};
-+
-+void dal_pixel_format_list_reset_iterator(struct pixel_format_list *pfl);
-+void dal_pixel_format_list_zero_iterator(struct pixel_format_list *pfl);
-+
-+void dal_pixel_format_list_construct(
-+ struct pixel_format_list *pfl,
-+ uint32_t mask);
-+
-+uint32_t dal_pixel_format_list_next(struct pixel_format_list *pfl);
-+
-+uint32_t dal_pixel_format_list_get_count(
-+ const struct pixel_format_list *pfl);
-+enum pixel_format dal_pixel_format_list_get_pixel_format(
-+ const struct pixel_format_list *pfl);
-+
-+#endif /* __DAL_MODE_MANAGER_TYPES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/mode_query_interface.h b/drivers/gpu/drm/amd/dal/include/mode_query_interface.h
-new file mode 100644
-index 0000000..1d20e73
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/mode_query_interface.h
-@@ -0,0 +1,93 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_MODE_QUERY_INTERFACE_H__
-+#define __DAL_MODE_QUERY_INTERFACE_H__
-+
-+#include "include/set_mode_types.h"
-+#include "include/mode_manager_types.h"
-+
-+enum query_option {
-+ QUERY_OPTION_ALLOW_PAN,
-+ QUERY_OPTION_ALLOW_PAN_NO_VIEW_RESTRICTION,
-+ QUERY_OPTION_PAN_ON_LIMITED_RESOLUTION_DISP_PATH,
-+ QUERY_OPTION_NO_PAN,
-+ QUERY_OPTION_NO_PAN_NO_DISPLAY_VIEW_RESTRICTION,
-+ QUERY_OPTION_3D_LIMITED_CANDIDATES,
-+ QUERY_OPTION_TILED_DISPLAY_PREFERRED,
-+ QUERY_OPTION_MAX,
-+};
-+
-+struct topology {
-+ uint32_t disp_path_num;
-+ uint32_t display_index[MAX_COFUNC_PATH];
-+};
-+
-+struct path_mode;
-+struct mode_query;
-+
-+bool dal_mode_query_pin_path_mode(
-+ struct mode_query *mq,
-+ const struct path_mode *path_mode);
-+
-+const struct render_mode *dal_mode_query_get_current_render_mode(
-+ const struct mode_query *mq);
-+
-+const struct stereo_3d_view *dal_mode_query_get_current_3d_view(
-+ const struct mode_query *mq);
-+
-+const struct refresh_rate *dal_mode_query_get_current_refresh_rate(
-+ const struct mode_query *mq);
-+
-+const struct path_mode_set *dal_mode_query_get_current_path_mode_set(
-+ const struct mode_query *mq);
-+
-+bool dal_mode_query_select_first(struct mode_query *mq);
-+bool dal_mode_query_select_next_render_mode(struct mode_query *mq);
-+
-+bool dal_mode_query_select_render_mode(struct mode_query *mq,
-+ const struct render_mode *render_mode);
-+
-+bool dal_mode_query_select_next_view_3d_format(struct mode_query *mq);
-+bool dal_mode_query_select_view_3d_format(
-+ struct mode_query *mq,
-+ enum view_3d_format format);
-+
-+bool dal_mode_query_select_refresh_rate(struct mode_query *mq,
-+ const struct refresh_rate *refresh_rate);
-+
-+bool dal_mode_query_select_refresh_rate_ex(struct mode_query *mq,
-+ uint32_t refresh_rate,
-+ bool interlaced);
-+
-+bool dal_mode_query_select_next_scaling(struct mode_query *mq);
-+
-+bool dal_mode_query_select_next_refresh_rate(struct mode_query *mq);
-+
-+bool dal_mode_query_base_select_next_scaling(struct mode_query *mq);
-+
-+void dal_mode_query_destroy(struct mode_query **mq);
-+
-+#endif /* __DAL_MODE_QUERY_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/mode_timing_list_interface.h b/drivers/gpu/drm/amd/dal/include/mode_timing_list_interface.h
-new file mode 100644
-index 0000000..a558fec
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/mode_timing_list_interface.h
-@@ -0,0 +1,51 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_MODE_TIMING_LIST_INTERFACE_H__
-+#define __DAL_MODE_TIMING_LIST_INTERFACE_H__
-+
-+
-+struct mode_timing_filter;
-+struct mode_timing_list;
-+
-+struct mode_timing_list *dal_mode_timing_list_create(
-+ struct dal_context *ctx,
-+ uint32_t display_index,
-+ const struct mode_timing_filter *mt_filter);
-+
-+void dal_mode_timing_list_destroy(struct mode_timing_list **mtl);
-+
-+
-+uint32_t dal_mode_timing_list_get_count(
-+ const struct mode_timing_list *mode_timing_list);
-+
-+const struct dc_mode_timing *dal_mode_timing_list_get_timing_at_index(
-+ const struct mode_timing_list *mode_timing_list,
-+ uint32_t index);
-+
-+const struct dc_mode_timing *dal_mode_timing_list_get_single_selected_mode_timing(
-+ const struct mode_timing_list *mode_timing_list);
-+
-+#endif /*__DAL_MODE_TIMING_LIST_INTERFACE_H__*/
-diff --git a/drivers/gpu/drm/amd/dal/include/overlay_interface.h b/drivers/gpu/drm/amd/dal/include/overlay_interface.h
-new file mode 100644
-index 0000000..c33bd73
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/overlay_interface.h
-@@ -0,0 +1,137 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_OVERLAY_INTERFACE_H__
-+#define __DAL_OVERLAY_INTERFACE_H__
-+
-+#include "include/overlay_types.h"
-+#include "include/display_service_types.h"
-+
-+struct ds_overlay;
-+struct path_mode_set;
-+struct path_mode;
-+struct view;
-+
-+bool dal_ds_overlay_is_active(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index);
-+
-+uint32_t dal_ds_overlay_get_controller_handle(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index);
-+
-+enum ds_return dal_ds_overlay_alloc(
-+ struct ds_overlay *ovl,
-+ struct path_mode_set *path_mode_set,
-+ uint32_t display_index,
-+ struct view *view,
-+ struct overlay_data *data);
-+
-+enum ds_return dal_ds_overlay_validate(
-+ struct ds_overlay *ovl,
-+ struct path_mode_set *path_mode_set,
-+ uint32_t display_index,
-+ struct view *view,
-+ struct overlay_data *data);
-+
-+enum ds_return dal_ds_overlay_free(
-+ struct ds_overlay *ovl,
-+ struct path_mode_set *path_mode_set,
-+ uint32_t display_index);
-+
-+enum ds_return dal_ds_overlay_get_info(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index,
-+ enum overlay_color_space *color_space,
-+ enum overlay_backend_bpp *backend_bpp,
-+ enum overlay_alloc_option *alloc_option,
-+ enum overlay_format *surface_format);
-+
-+enum ds_return dal_ds_overlay_set_otm(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index,
-+ const struct path_mode *current_path_mode);
-+
-+enum ds_return dal_ds_overlay_reset_otm(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index,
-+ struct path_mode **saved_path_mode);
-+
-+/**is in overlay theater mode*/
-+bool dal_ds_overlay_is_in_otm(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index);
-+
-+void dal_ds_overlay_set_matrix(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index,
-+ const struct overlay_color_matrix *matrix);
-+
-+void dal_ds_overlay_reset_matrix(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index,
-+ enum overlay_csc_matrix_type type);
-+
-+const struct overlay_color_matrix *dal_ds_overlay_get_matrix(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index,
-+ enum overlay_csc_matrix_type type);
-+
-+bool dal_ds_overlay_set_color_space(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index,
-+ enum overlay_color_space space);
-+
-+bool dal_ds_overlay_get_display_pixel_encoding(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index,
-+ enum display_pixel_encoding *pixel_encoding);
-+
-+bool dal_ds_overlay_set_display_pixel_encoding(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index,
-+ enum display_pixel_encoding pixel_encoding);
-+
-+bool dal_ds_overlay_reset_display_pixel_encoding(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index);
-+
-+/*After Set Overlay Theatre Mode (OTM) on a display path,
-+ * saving the passed setting of Gpu scaling option for later restore*/
-+enum ds_return dal_ds_overlay_save_gpu_scaling_before_otm(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index,
-+ int32_t timing_sel_before_otm);
-+
-+/* After reset Overlay Theatre Mode (OTM) on a display path,
-+ * returning the previous Gpu scaling option by SetOverlayTheatreMode*/
-+enum ds_return dal_ds_overlay_get_gpu_scaling_before_otm(
-+ struct ds_overlay *ovl,
-+ uint32_t display_index,
-+ int32_t *timing_sel_before_otm);
-+
-+uint32_t dal_ds_overlay_get_num_of_allowed(struct ds_overlay *ovl);
-+
-+#endif /* __DAL_OVERLAY_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/overlay_types.h b/drivers/gpu/drm/amd/dal/include/overlay_types.h
-new file mode 100644
-index 0000000..c001edf
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/overlay_types.h
-@@ -0,0 +1,164 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_OVERLAY_TYPES_H__
-+#define __DAL_OVERLAY_TYPES_H__
-+
-+enum overlay_color_space {
-+ OVERLAY_COLOR_SPACE_UNINITIALIZED,
-+ OVERLAY_COLOR_SPACE_RGB, /* the first*/
-+ OVERLAY_COLOR_SPACE_BT601,
-+ OVERLAY_COLOR_SPACE_BT709, /* the last*/
-+ OVERLAY_COLOR_SPACE_INVALID,
-+
-+ /* flag the first and last*/
-+ OVERLAY_COLOR_SPACE_BEGIN = OVERLAY_COLOR_SPACE_RGB,
-+ OVERLAY_COLOR_SPACE_END = OVERLAY_COLOR_SPACE_BT709,
-+};
-+
-+enum overlay_backend_bpp {
-+ OVERLAY_BACKENDBPP_UNINITIALIZED,
-+
-+ OVERLAY_BACKEND_BPP_32_FULL_BANDWIDTH,/* the first*/
-+ OVERLAY_BACKEND_BPP_16_FULL_BANDWIDTH,
-+ OVERLAY_BACKEND_BPP_32_HALF_BANDWIDTH,/* the last*/
-+
-+ OVERLAY_BACKEND_BPP_INVALID,
-+
-+ /* flag the first and last*/
-+ OVERLAY_BACKEND_BPP_BEGIN = OVERLAY_BACKEND_BPP_32_FULL_BANDWIDTH,
-+ OVERLAY_BACKEND_BPP_END = OVERLAY_BACKEND_BPP_32_HALF_BANDWIDTH,
-+};
-+
-+enum overlay_alloc_option {
-+ OVERLAY_ALLOC_OPTION_UNINITIALIZED,
-+
-+ OVERLAY_ALLOC_OPTION_APPLY_OVERLAY_CSC, /* the first*/
-+ OVERLAY_ALLOC_OPTION_APPLY_DESKTOP_CSC, /* the last*/
-+
-+ OVERLAY_ALLOC_OPTION_INVALID,
-+
-+ /* flag the first and last*/
-+ OVERLAY_ALLOC_OPTION_BEGIN = OVERLAY_ALLOC_OPTION_APPLY_OVERLAY_CSC,
-+ OVERLAY_ALLOC_OPTION_END = OVERLAY_ALLOC_OPTION_APPLY_DESKTOP_CSC,
-+};
-+
-+enum overlay_format {
-+ OVERLAY_FORMAT_UNINITIALIZED,
-+ OVERLAY_FORMAT_YUY2,
-+ OVERLAY_FORMAT_UYVY,
-+ OVERLAY_FORMAT_RGB565,
-+ OVERLAY_FORMAT_RGB555,
-+ OVERLAY_FORMAT_RGB32,
-+ OVERLAY_FORMAT_YUV444,
-+ OVERLAY_FORMAT_RGB32_2101010,
-+
-+ OVERLAY_FORMAT_INVALID,
-+
-+ /* flag the first and last*/
-+ OVERLAY_FORMAT_BEGIN = OVERLAY_FORMAT_YUY2,
-+ OVERLAY_FORMAT_END = OVERLAY_FORMAT_RGB32_2101010,
-+};
-+
-+enum display_pixel_encoding {
-+ DISPLAY_PIXEL_ENCODING_UNDEFINED = 0,
-+ DISPLAY_PIXEL_ENCODING_RGB,
-+ DISPLAY_PIXEL_ENCODING_YCBCR422,
-+ DISPLAY_PIXEL_ENCODING_YCBCR444
-+};
-+
-+union overlay_data_status {
-+ uint32_t u32all;
-+ struct {
-+ uint32_t COLOR_SPACE_SET:1;
-+ uint32_t BACKEND_BPP:1;
-+ uint32_t ALLOC_OPTION:1;
-+ uint32_t SURFACE_FORMAT:1;
-+ uint32_t PIXEL_ENCODING:1;
-+ uint32_t reserved:27;
-+
-+ } bits;
-+};
-+
-+struct overlay_data {
-+ enum overlay_color_space color_space;
-+ enum overlay_backend_bpp backend_bpp;
-+ enum overlay_alloc_option alloc_option;
-+ enum overlay_format surface_format;
-+};
-+
-+enum overlay_csc_matrix_type {
-+ OVERLAY_CSC_MATRIX_NOTDEFINED = 0,
-+ OVERLAY_CSC_MATRIX_BT709,
-+ OVERLAY_CSC_MATRIX_BT601,
-+ OVERLAY_CSC_MATRIX_SMPTE240,
-+ OVERLAY_CSC_MATRIX_SRGB,
-+};
-+
-+#define DEFAULT_APP_MATRIX_DIVIDER 10000
-+#define MAX_OVL_MATRIX_COUNTS 2
-+#define OVL_BT709 0
-+#define OVL_BT601 1
-+
-+#define OVL_MATRIX_ITEM 9
-+#define OVL_MATRIX_OFFSET_ITEM 3
-+
-+struct overlay_color_matrix {
-+ enum overlay_csc_matrix_type csc_matrix;
-+/*3*3 Gamut Matrix (value is the real value * M_GAMUT_PRECISION_MULTIPLIER)*/
-+ int32_t matrix_settings[OVL_MATRIX_ITEM];
-+ int32_t offsets[OVL_MATRIX_OFFSET_ITEM];
-+};
-+
-+enum setup_adjustment_ovl_value_type {
-+ SETUP_ADJUSTMENT_MIN,
-+ SETUP_ADJUSTMENT_MAX,
-+ SETUP_ADJUSTMENT_DEF,
-+ SETUP_ADJUSTMENT_CURRENT,
-+ SETUP_ADJUSTMENT_BUNDLE_MIN,
-+ SETUP_ADJUSTMENT_BUNDLE_MAX,
-+ SETUP_ADJUSTMENT_BUNDLE_DEF,
-+ SETUP_ADJUSTMENT_BUNDLE_CURRENT
-+};
-+
-+struct overlay_parameter {
-+ union {
-+ uint32_t u32all;
-+ struct {
-+ uint32_t VALID_OVL_COLOR_SPACE:1;
-+ uint32_t VALID_VALUE_TYPE:1;
-+ uint32_t VALID_OVL_SURFACE_FORMAT:1;
-+ uint32_t CONFIG_IS_CHANGED:1;
-+ uint32_t reserved:28;
-+
-+ } bits;
-+ };
-+ /*currently colorSpace here packed, continue this list*/
-+ enum overlay_color_space color_space;
-+ enum setup_adjustment_ovl_value_type value_type;
-+ enum overlay_format surface_format;
-+};
-+
-+#endif /* OVERLAY_TYPES_H_ */
-diff --git a/drivers/gpu/drm/amd/dal/include/path_mode_set_interface.h b/drivers/gpu/drm/amd/dal/include/path_mode_set_interface.h
-new file mode 100644
-index 0000000..a277010
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/path_mode_set_interface.h
-@@ -0,0 +1,107 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_PATH_MODE_SET_INTERFACE_H__
-+#define __DAL_PATH_MODE_SET_INTERFACE_H__
-+
-+/* Set of path modes */
-+struct path_mode_set {
-+ union control_flags {
-+ struct {
-+ uint32_t KEEP_DISPLAY_POWERED_OFF:1;
-+ uint32_t UNBLANCK_SOURCE_AFTER_SETMODE:1;
-+ uint32_t NODE_FAULT_UNDERSCAN:1;
-+ } bits;
-+
-+ uint32_t all;
-+ } control_flags;
-+
-+ struct path_mode path_mode_set[MAX_COFUNC_PATH];
-+ uint32_t count;
-+};
-+
-+/* Create path mode set */
-+struct path_mode_set *dal_pms_create(void);
-+
-+/* Deallocate path mode set */
-+void dal_pms_destroy(
-+ struct path_mode_set **pms);
-+
-+/* Create a copy of given path mode set */
-+struct path_mode_set *dal_pms_copy(
-+ const struct path_mode_set *copy);
-+
-+/* Constructor for path mode set */
-+bool dal_pms_construct(
-+ struct path_mode_set *set);
-+
-+/* Add a path mode into the set */
-+bool dal_pms_add_path_mode(
-+ struct path_mode_set *set,
-+ const struct path_mode *path_mode);
-+
-+/* Get number of path modes in the set */
-+uint32_t dal_pms_get_path_mode_num(
-+ const struct path_mode_set *set);
-+
-+/* Return the path mode at the index */
-+const struct path_mode *dal_pms_get_path_mode_at_index(
-+ const struct path_mode_set *set,
-+ uint32_t index);
-+
-+/* Return the path mode for the given display index */
-+const struct path_mode *dal_pms_get_path_mode_for_display_index(
-+ const struct path_mode_set *set,
-+ uint32_t index);
-+
-+/* Remove the path mode at index */
-+bool dal_pms_remove_path_mode_at_index(
-+ struct path_mode_set *set,
-+ uint32_t index);
-+
-+/* Remove the given path mode if it is found in the set */
-+bool dal_pms_remove_path_mode(
-+ struct path_mode_set *set,
-+ struct path_mode *mode);
-+
-+/* Add control flag to keep display powered off */
-+void dal_pms_keep_display_powered_off(
-+ struct path_mode_set *set,
-+ bool keep);
-+
-+/* Return control flag if display needs to be kept powered off */
-+bool dal_pms_is_display_power_off_required(
-+ const struct path_mode_set *set);
-+
-+/* Add control flag to not use default underscan*/
-+void dal_pms_fallback_remove_default_underscan(
-+ struct path_mode_set *set,
-+ bool lean);
-+
-+/* Return control flag if default underscan is not used */
-+bool dal_pms_is_fallback_no_default_underscan_enabled(
-+ struct path_mode_set *set);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/plane_types.h b/drivers/gpu/drm/amd/dal/include/plane_types.h
-new file mode 100644
-index 0000000..a2a8939
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/plane_types.h
-@@ -0,0 +1,309 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_PLANE_TYPES_H__
-+#define __DAL_PLANE_TYPES_H__
-+
-+#include "scaler_types.h"
-+
-+enum display_flip_mode {
-+ DISPLAY_FLIP_MODE_VERTICAL = 0,
-+ DISPLAY_FLIP_MODE_HORIZONTAL
-+};
-+
-+/*rect or view */
-+struct rect_position {
-+ uint32_t x;
-+ uint32_t y;
-+};
-+
-+union plane_config_change_flags {
-+ struct {
-+ uint32_t MIRROR_FLAGS:1;
-+ uint32_t BLEND_FLAGS:1;
-+ uint32_t COLORIMETRY:1;
-+ uint32_t SCALING_RECTS:1;
-+
-+ uint32_t SCALING_QUALITY:1;
-+ uint32_t VIDEO_SCAN_FORMAT:1;
-+ uint32_t STEREO_FORMAT:1;
-+ uint32_t PLANE_SIZE:1;
-+
-+ uint32_t TITLING_INFO:1;
-+ uint32_t FORMAT:1;
-+ uint32_t ROTATION:1;
-+
-+ uint32_t RESERVED:21;
-+ } bits;
-+ uint32_t value;
-+};
-+
-+
-+enum array_mode {
-+ ARRAY_MODE_LINEAR_GENERAL = 0x00000000,
-+ ARRAY_MODE_LINEAR_ALIGNED = 0x00000001,
-+ ARRAY_MODE_1D_TILED_THIN1 = 0x00000002,
-+ ARRAY_MODE_1D_TILED_THICK = 0x00000003,
-+ ARRAY_MODE_2D_TILED_THIN1 = 0x00000004,
-+ ARRAY_MODE_PRT_TILED_THIN1 = 0x00000005,
-+ ARRAY_MODE_PRT_2D_TILED_THIN1 = 0x00000006,
-+ ARRAY_MODE_2D_TILED_THICK = 0x00000007,
-+ ARRAY_MODE_2D_TILED_X_THICK = 0x00000008,
-+ ARRAY_MODE_PRT_TILED_THICK = 0x00000009,
-+ ARRAY_MODE_PRT_2D_TILED_THICK = 0x0000000a,
-+ ARRAY_MODE_PRT_3D_TILED_THIN1 = 0x0000000b,
-+ ARRAY_MODE_3D_TILED_THIN1 = 0x0000000c,
-+ ARRAY_MODE_3D_TILED_THICK = 0x0000000d,
-+ ARRAY_MODE_3D_TILED_X_THICK = 0x0000000e,
-+ ARRAY_MODE_PRT_3D_TILED_THICK = 0x0000000f
-+};
-+
-+/* single enum for grph and video (both luma and chroma) */
-+enum tile_split {
-+ TILE_SPLIT_64B = 0x00000000,
-+ TILE_SPLIT_128B = 0x00000001,
-+ TILE_SPLIT_256B = 0x00000002,
-+ TILE_SPLIT_512B = 0x00000003,
-+ TILE_SPLIT_1KB = 0x00000004,
-+ TILE_SPLIT_2KB = 0x00000005,
-+ TILE_SPLIT_4KB = 0x00000006
-+};
-+
-+/* single enum for grph and video (both luma and chroma)*/
-+enum macro_tile_aspect {
-+ MACRO_TILE_ASPECT_1 = 0x00000000,
-+ MACRO_TILE_ASPECT_2 = 0x00000001,
-+ MACRO_TILE_ASPECT_4 = 0x00000002,
-+ MACRO_TILE_ASPECT_8 = 0x00000003
-+};
-+
-+enum video_array_mode {
-+ VIDEO_ARRAY_MODE_LINEAR_GENERAL = 0x00000000,
-+ VIDEO_ARRAY_MODE_LINEAR_ALIGNED = 0x00000001,
-+ VIDEO_ARRAY_MODE_1D_TILED_THIN1 = 0x00000002,
-+ VIDEO_ARRAY_MODE_1D_TILED_THICK = 0x00000003,
-+ VIDEO_ARRAY_MODE_2D_TILED_THIN1 = 0x00000004,
-+ VIDEO_ARRAY_MODE_2D_TILED_THICK = 0x00000007,
-+ VIDEO_ARRAY_MODE_3D_TILED_THIN1 = 0x0000000c,
-+ VIDEO_ARRAY_MODE_3D_TILED_THICK = 0x0000000d
-+};
-+
-+/* single enum for grph and video (both luma and chroma)*/
-+enum micro_tile_mode {
-+ MICRO_TILE_MODE_DISPLAY = 0x00000000,
-+ MICRO_TILE_MODE_THIN = 0x00000001,
-+ MICRO_TILE_MODE_DEPTH = 0x00000002,
-+ MICRO_TILE_MODE_ROTATED = 0x00000003
-+};
-+
-+/* KK: taken from addrlib*/
-+enum addr_pipe_config {
-+ ADDR_PIPE_CONFIG_INVALID = 0,
-+ /* 2 pipes */
-+ ADDR_PIPE_CONFIG_P2 = 1,
-+ /* 4 pipes */
-+ ADDR_PIPE_CONFIG_P4_8x16 = 5,
-+ ADDR_PIPE_CONFIG_P4_16x16 = 6,
-+ ADDR_PIPE_CONFIG_P4_16x32 = 7,
-+ ADDR_PIPE_CONFIG_P4_32x32 = 8,
-+ /* 8 pipes*/
-+ ADDR_PIPE_CONFIG_P8_16x16_8x16 = 9,
-+ ADDR_PIPE_CONFIG_P8_16x32_8x16 = 10,
-+ ADDR_PIPE_CONFIG_P8_32x32_8x16 = 11,
-+ ADDR_PIPE_CONFIG_P8_16x32_16x16 = 12,
-+ ADDR_PIPE_CONFIG_P8_32x32_16x16 = 13,
-+ ADDR_PIPE_CONFIG_P8_32x32_16x32 = 14,
-+ ADDR_PIPE_CONFIG_P8_32x64_32x32 = 15,
-+ /* 16 pipes */
-+ ADDR_PIPE_CONFIG_P16_32x32_8x16 = 17,
-+ ADDR_PIPE_CONFIG_P16_32x32_16x16 = 18,
-+ ADDR_PIPE_CONFIG_MAX = 19
-+};
-+
-+struct plane_surface_config {
-+ uint32_t layer_index;
-+ /*used in set operation*/
-+ bool enabled;
-+
-+ union plane_size plane_size;
-+ union plane_tiling_info tiling_info;
-+ /* surface pixel format from display manager or fb*/
-+ enum surface_pixel_format format;
-+ /*pixel format for DAL internal hardware programming*/
-+ enum pixel_format dal_pixel_format;
-+ enum dc_rotation_angle rotation;
-+};
-+
-+/* For Caps, maximum taps for each axis is returned*/
-+/* For Set, the requested taps will be used*/
-+struct plane_src_scaling_quality {
-+ /* INVALID_TAP_VALUE indicates DAL
-+ * decides considering aspect ratio
-+ * & bandwidth
-+ */
-+ uint32_t h_taps;
-+ /* INVALID_TAP_VALUE indicates DAL
-+ * decides considering aspect ratio
-+ * & bandwidth
-+ */
-+ uint32_t v_taps;
-+ uint32_t h_taps_c;
-+ uint32_t v_taps_c;
-+};
-+
-+struct plane_mirror_flags {
-+ union {
-+ struct {
-+ uint32_t vertical_mirror:1;
-+ uint32_t horizontal_mirror:1;
-+ uint32_t reserved:30;
-+ } bits;
-+ uint32_t value;
-+ };
-+};
-+
-+/* Note some combinations are mutually exclusive*/
-+struct plane_blend_flags {
-+ union {
-+ struct {
-+ uint32_t PER_PIXEL_ALPHA_BLEND:1;
-+ uint32_t GLOBAL_ALPHA_BLEND:1;
-+ uint32_t RESERVED:30;
-+ } bits;
-+ uint32_t value;
-+ };
-+};
-+
-+enum plane_vid_scan_fmt {
-+ PLANE_VID_SCAN_FMT_PROGRESSIVE = 0,
-+ PLANE_VID_SCAN_FMT_INTERLACED_TOP_FIRST = 1,
-+ PLANE_VID_SCAN_FMT_INTERLACED_BOTTOM_FIRST = 2
-+};
-+
-+
-+struct plane_attributes {
-+ /*mirror options */
-+ struct plane_mirror_flags mirror_flags;
-+ /*blending options*/
-+ struct plane_blend_flags blend_flags;
-+ /*color space */
-+ struct plane_colorimetry colorimetry;
-+
-+ struct rect src_rect;
-+ struct rect dst_rect;
-+ struct rect clip_rect;
-+ struct scaling_taps scaling_quality;
-+ /*progressive, interlaced*/
-+ enum plane_vid_scan_fmt video_scan_format;
-+ enum plane_stereo_format stereo_format;
-+};
-+
-+union address_flags {
-+ struct {
-+ /* always 1 for primary surface, used in get operation*/
-+ uint32_t ENABLE:1;
-+ /* set 1 if returned address is from cache*/
-+ uint32_t ADDR_IS_PENDING:1;
-+ /* currentFrameIsRightEye for stereo only*/
-+ uint32_t CURRENT_FRAME_IS_RIGHT_EYE:1;
-+ uint32_t RESERVED:29;
-+ } bits;
-+
-+ uint32_t value;
-+};
-+
-+struct address_info {
-+ /* primary surface will be DAL_LAYER_INDEX_PRIMARY*/
-+ int32_t layer_index;
-+ /*the flags to describe the address info*/
-+ union address_flags flags;
-+ struct dc_plane_address address;
-+};
-+
-+union plane_valid_mask {
-+ struct {
-+ /* set 1 if config is valid in DalPlane*/
-+ uint32_t SURFACE_CONFIG_IS_VALID:1;
-+ /* set 1 if plane_attributes is valid in plane*/
-+ uint32_t PLANE_ATTRIBUTE_IS_VALID:1;
-+ uint32_t RESERVED:30;
-+ } bits;
-+ uint32_t value;
-+};
-+
-+union flip_valid_mask {
-+ struct {
-+ /* set 1 if flip_immediate is
-+ * valid in plane_addr_flip_info
-+ */
-+ uint32_t FLIP_VALID:1;
-+ /* set 1 if addressInfo is
-+ * valid in plane_addr_flip_info
-+ */
-+ uint32_t ADDRESS_VALID:1;
-+ uint32_t RESERVED:30;
-+ } bits;
-+ uint32_t value;
-+};
-+
-+struct plane_addr_flip_info {
-+ uint32_t display_index;
-+ struct address_info address_info;
-+ /* flip on vsync if false . When
-+ * flip_immediate is true then
-+ * update_duration is unused
-+ */
-+ bool flip_immediate;
-+ /* 48 Hz support for single and
-+ * multi plane cases ,set 0 when
-+ * it is unused.
-+ */
-+ uint32_t update_duration;
-+ union flip_valid_mask mask;
-+};
-+
-+struct plane_config {
-+ union plane_valid_mask mask;
-+ uint32_t display_index;
-+ struct plane_surface_config config;
-+ struct plane_attributes attributes;
-+ struct mp_scaling_data mp_scaling_data;
-+ union plane_config_change_flags plane_change_flags;
-+};
-+
-+struct plane_validate_config {
-+ uint32_t display_index;
-+ bool flip_immediate;
-+ struct plane_surface_config config;
-+ struct plane_attributes attributes;
-+};
-+
-+struct view_port {
-+ uint32_t display_index;
-+ struct rect view_port_rect;
-+};
-+
-+#endif
-+
-diff --git a/drivers/gpu/drm/amd/dal/include/scaler_types.h b/drivers/gpu/drm/amd/dal/include/scaler_types.h
-new file mode 100644
-index 0000000..db52dbc
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/scaler_types.h
-@@ -0,0 +1,196 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_SCALER_TYPES_H__
-+#define __DAL_SCALER_TYPES_H__
-+
-+#include "signal_types.h"
-+#include "fixed31_32.h"
-+#include "dc_types.h"
-+
-+enum pixel_type {
-+ PIXEL_TYPE_30BPP = 1,
-+ PIXEL_TYPE_20BPP
-+};
-+
-+/*overscan or window*/
-+struct overscan_info {
-+ uint32_t left;
-+ uint32_t right;
-+ uint32_t top;
-+ uint32_t bottom;
-+};
-+
-+struct mp_scaling_data {
-+ struct rect viewport;
-+ struct view dst_res;
-+ struct overscan_info overscan;
-+ struct scaling_taps taps;
-+ struct scaling_ratios ratios;
-+};
-+
-+struct scaler_validation_params {
-+ uint32_t INTERLACED:1;
-+ uint32_t CHROMA_SUB_SAMPLING:1;
-+
-+ uint32_t line_buffer_size;
-+ uint32_t display_clock; /* in KHz */
-+ uint32_t actual_pixel_clock; /* in KHz */
-+ struct view source_view;
-+ struct view dest_view;
-+ enum signal_type signal_type;
-+
-+ struct scaling_taps taps_requested;
-+ enum pixel_format pixel_format;
-+ enum dc_rotation_angle rotation;
-+};
-+
-+struct adjustment_factor {
-+ int32_t adjust; /* Actual adjustment value * lDivider */
-+ uint32_t divider;
-+};
-+
-+struct sharpness_adjustment {
-+ int32_t sharpness;
-+ bool enable_sharpening;
-+};
-+
-+enum scaling_options {
-+ SCALING_BYPASS = 0,
-+ SCALING_ENABLE
-+};
-+
-+/* same as Hw register */
-+enum filter_type {
-+ FILTER_TYPE_V_LOW_PASS = 0x0,
-+ FILTER_TYPE_V_HIGH_PASS = 0x1,
-+ FILTER_TYPE_H_LUMA = 0x2,
-+ FILTER_TYPE_H_CHROMA = 0x3
-+};
-+
-+/* Validation Result enumeration */
-+enum scaler_validation_code {
-+ SCALER_VALIDATION_OK = 0,
-+ SCALER_VALIDATION_INVALID_INPUT_PARAMETERS,
-+ SCALER_VALIDATION_SCALING_RATIO_NOT_SUPPORTED,
-+ SCALER_VALIDATION_SOURCE_VIEW_WIDTH_EXCEEDING_LIMIT,
-+ SCALER_VALIDATION_DISPLAY_CLOCK_BELOW_PIXEL_CLOCK,
-+ SCALER_VALIDATION_FAILURE_PREDEFINED_TAPS_NUMBER
-+};
-+
-+
-+#define FILTER_TYPE_MASK 0x0000000FL
-+#define TWO_TAPS 2
-+
-+struct init_int_and_frac {
-+ uint32_t integer;
-+ uint32_t fraction;
-+};
-+
-+struct scl_ratios_inits {
-+ uint32_t bottom_enable;
-+ uint32_t h_int_scale_ratio;
-+ uint32_t v_int_scale_ratio;
-+ struct init_int_and_frac h_init;
-+ struct init_int_and_frac v_init;
-+ struct init_int_and_frac v_init_bottom;
-+};
-+
-+union scaler_flags {
-+ uint32_t raw;
-+ struct {
-+ uint32_t INTERLACED:1;
-+ uint32_t DOUBLE_SCAN_MODE:1;
-+ /* this one is legacy flag only used in DCE80 */
-+ uint32_t RGB_COLOR_SPACE:1;
-+ uint32_t PIPE_LOCK_REQ:1;
-+ /* 4 */
-+ uint32_t WIDE_DISPLAY:1;
-+ uint32_t OTHER_PIPE:1;
-+ uint32_t SHOULD_PROGRAM_VIEWPORT:1;
-+ uint32_t SHOULD_UNLOCK:1;
-+ /* 8 */
-+ uint32_t SHOULD_PROGRAM_ALPHA:1;
-+ uint32_t SHOW_COLOURED_BORDER:1;
-+
-+ uint32_t RESERVED:22;
-+ } bits;
-+};
-+
-+struct scaler_data {
-+ struct view src_res;
-+ struct view dst_res;
-+ struct overscan_info overscan;
-+ struct scaling_taps taps;
-+ struct adjustment_factor scale_ratio_hp_factor;
-+ struct adjustment_factor scale_ratio_lp_factor;
-+ enum pixel_type pixel_type; /*legacy*/
-+ struct sharpness_adjustment sharp_gain;
-+
-+ union scaler_flags flags;
-+ int32_t h_sharpness;
-+ int32_t v_sharpness;
-+
-+ struct view src_res_wide_display;
-+ struct view dst_res_wide_display;
-+
-+ /* it is here because of the HW bug in NI (UBTS #269539)
-+ causes glitches in this VBI signal. It shouldn't change after
-+ initialization, kind of a const */
-+ const struct hw_crtc_timing *hw_crtc_timing;
-+
-+ struct rect viewport;
-+
-+ enum pixel_format dal_pixel_format;/*plane concept*/
-+ /*stereoformat TODO*/
-+ /*hwtotation TODO*/
-+
-+ const struct scaling_ratios *ratios;
-+};
-+
-+enum bypass_type {
-+ /* 00 - 00 - Manual Centering, Manual Replication */
-+ BYPASS_TYPE_MANUAL = 0,
-+ /* 01 - 01 - Auto-Centering, No Replication */
-+ BYPASS_TYPE_AUTO_CENTER = 1,
-+ /* 02 - 10 - Auto-Centering, Auto-Replication */
-+ BYPASS_TYPE_AUTO_REPLICATION = 3
-+};
-+
-+struct replication_factor {
-+ uint32_t h_manual;
-+ uint32_t v_manual;
-+};
-+
-+enum ram_filter_type {
-+ FILTER_TYPE_RGB_Y_VERTICAL = 0, /* 0 - RGB/Y Vertical filter */
-+ FILTER_TYPE_CBCR_VERTICAL = 1, /* 1 - CbCr Vertical filter */
-+ FILTER_TYPE_RGB_Y_HORIZONTAL = 2, /* 1 - RGB/Y Horizontal filter */
-+ FILTER_TYPE_CBCR_HORIZONTAL = 3, /* 3 - CbCr Horizontal filter */
-+ FILTER_TYPE_ALPHA_VERTICAL = 4, /* 4 - Alpha Vertical filter. */
-+ FILTER_TYPE_ALPHA_HORIZONTAL = 5, /* 5 - Alpha Horizontal filter. */
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/set_mode_params_interface.h b/drivers/gpu/drm/amd/dal/include/set_mode_params_interface.h
-new file mode 100644
-index 0000000..e4f52c4
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/set_mode_params_interface.h
-@@ -0,0 +1,101 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_SET_MODE_PARAMS_INTERFACE_H__
-+#define __DAL_SET_MODE_PARAMS_INTERFACE_H__
-+
-+struct set_mode_params;
-+
-+struct set_mode_params_init_data {
-+ struct hw_sequencer *hws;
-+ struct dal_context *ctx;
-+ struct topology_mgr *tm;
-+};
-+
-+struct view_stereo_3d_support dal_set_mode_params_get_stereo_3d_support(
-+ struct set_mode_params *smp,
-+ uint32_t display_index,
-+ enum dc_timing_3d_format);
-+
-+bool dal_set_mode_params_update_view_on_path(
-+ struct set_mode_params *smp,
-+ uint32_t display_index,
-+ const struct view *vw);
-+
-+bool dal_set_mode_params_update_mode_timing_on_path(
-+ struct set_mode_params *smp,
-+ uint32_t display_index,
-+ const struct dc_mode_timing *mode_timing,
-+ enum view_3d_format format);
-+
-+bool dal_set_mode_params_update_scaling_on_path(
-+ struct set_mode_params *smp,
-+ uint32_t display_index,
-+ enum scaling_transformation st);
-+
-+bool dal_set_mode_params_update_pixel_format_on_path(
-+ struct set_mode_params *smp,
-+ uint32_t display_index,
-+ enum pixel_format pf);
-+
-+bool dal_set_mode_params_update_tiling_mode_on_path(
-+ struct set_mode_params *smp,
-+ uint32_t display_index,
-+ enum tiling_mode tm);
-+
-+bool dal_set_mode_params_is_path_mode_set_supported(
-+ struct set_mode_params *smp);
-+
-+bool dal_set_mode_params_is_path_mode_set_guaranteed(
-+ struct set_mode_params *smp);
-+
-+bool dal_set_mode_params_report_single_selected_timing(
-+ struct set_mode_params *smp,
-+ uint32_t display_index);
-+
-+bool dal_set_mode_params_report_ce_mode_only(
-+ struct set_mode_params *smp,
-+ uint32_t display_index);
-+
-+struct set_mode_params *dal_set_mode_params_create(
-+ struct set_mode_params_init_data *init_data);
-+
-+bool dal_set_mode_params_init_with_topology(
-+ struct set_mode_params *smp,
-+ const uint32_t display_indicies[],
-+ uint32_t idx_num);
-+
-+bool dal_set_mode_params_is_multiple_pixel_encoding_supported(
-+ struct set_mode_params *smp,
-+ uint32_t display_index);
-+
-+enum dc_pixel_encoding dal_set_mode_params_get_default_pixel_format_preference(
-+ struct set_mode_params *smp,
-+ unsigned int display_index);
-+
-+void dal_set_mode_params_destroy(
-+ struct set_mode_params **set_mode_params);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/set_mode_types.h b/drivers/gpu/drm/amd/dal/include/set_mode_types.h
-new file mode 100644
-index 0000000..3647815
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/set_mode_types.h
-@@ -0,0 +1,285 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_SET_MODE_TYPES_H__
-+#define __DAL_SET_MODE_TYPES_H__
-+
-+#include "adjustment_types.h"
-+#include "hw_adjustment_types.h"
-+#include "include/plane_types.h"
-+#include "dc_types.h"
-+
-+/* Forward declaration */
-+struct dc_mode_timing;
-+struct display_path;
-+
-+/* State of stereo 3D for workstation */
-+enum ws_stereo_state {
-+ WS_STEREO_STATE_INACTIVE = 0,
-+ WS_STEREO_STATE_ACTIVE,
-+ WS_STEREO_STATE_ACTIVE_MASTER
-+};
-+
-+/* GTC group number */
-+enum gtc_group {
-+ GTC_GROUP_DISABLED,
-+ GTC_GROUP_1,
-+ GTC_GROUP_2,
-+ GTC_GROUP_3,
-+ GTC_GROUP_4,
-+ GTC_GROUP_5,
-+ GTC_GROUP_6,
-+ GTC_GROUP_MAX
-+};
-+
-+/* Adjustment action*/
-+enum adjustment_action {
-+ ADJUSTMENT_ACTION_UNDEFINED = 0,
-+ ADJUSTMENT_ACTION_VALIDATE,
-+ ADJUSTMENT_ACTION_SET_ADJUSTMENT
-+};
-+
-+/* Type of adjustment parameters*/
-+enum adjustment_par_type {
-+ ADJUSTMENT_PAR_TYPE_NONE = 0,
-+ ADJUSTMENT_PAR_TYPE_TIMING,
-+ ADJUSTMENT_PAR_TYPE_MODE
-+};
-+
-+/* Method of validation */
-+enum validation_method {
-+ VALIDATION_METHOD_STATIC = 0,
-+ VALIDATION_METHOD_DYNAMIC
-+};
-+
-+/* Info frame packet status */
-+enum info_frame_flag {
-+ INFO_PACKET_PACKET_INVALID = 0,
-+ INFO_PACKET_PACKET_VALID = 1,
-+ INFO_PACKET_PACKET_RESET = 2,
-+ INFO_PACKET_PACKET_UPDATE_SCAN_TYPE = 8
-+};
-+
-+/* Info frame types */
-+enum info_frame_type {
-+ INFO_FRAME_GAMUT = 0x0A,
-+ INFO_FRAME_VENDOR_INFO = 0x81,
-+ INFO_FRAME_AVI = 0x82
-+};
-+
-+/* Info frame versions */
-+enum info_frame_version {
-+ INFO_FRAME_VERSION_1 = 1,
-+ INFO_FRAME_VERSION_2 = 2,
-+ INFO_FRAME_VERSION_3 = 3
-+};
-+
-+/* Info frame size */
-+enum info_frame_size {
-+ INFO_FRAME_SIZE_AVI = 13,
-+ INFO_FRAME_SIZE_VENDOR = 25,
-+ INFO_FRAME_SIZE_AUDIO = 10
-+};
-+
-+/* Active format */
-+enum active_format_info {
-+ ACTIVE_FORMAT_NO_DATA = 0,
-+ ACTIVE_FORMAT_VALID = 1
-+};
-+/* Bar info */
-+enum bar_info {
-+ BAR_INFO_NOT_VALID = 0,
-+ BAR_INFO_VERTICAL_VALID = 1,
-+ BAR_INFO_HORIZONTAL_VALID = 2,
-+ BAR_INFO_BOTH_VALID = 3
-+};
-+
-+/* Picture scaling */
-+enum picture_scaling {
-+ PICTURE_SCALING_UNIFORM = 0,
-+ PICTURE_SCALING_HORIZONTAL = 1,
-+ PICTURE_SCALING_VERTICAL = 2,
-+ PICTURE_SCALING_BOTH = 3
-+};
-+
-+/* Colorimetry */
-+enum colorimetry {
-+ COLORIMETRY_NO_DATA = 0,
-+ COLORIMETRY_ITU601 = 1,
-+ COLORIMETRY_ITU709 = 2,
-+ COLORIMETRY_EXTENDED = 3
-+};
-+
-+/* ColorimetryEx */
-+enum colorimetry_ex {
-+ COLORIMETRY_EX_XVYCC601 = 0,
-+ COLORIMETRY_EX_XVYCC709 = 1,
-+ COLORIMETRY_EX_SYCC601 = 2,
-+ COLORIMETRY_EX_ADOBEYCC601 = 3,
-+ COLORIMETRY_EX_ADOBERGB = 4,
-+ COLORIMETRY_EX_RESERVED5 = 5,
-+ COLORIMETRY_EX_RESERVED6 = 6,
-+ COLORIMETRY_EX_RESERVED7 = 7
-+};
-+
-+/* Active format aspect ratio */
-+enum active_format_aspect_ratio {
-+ ACTIVE_FORMAT_ASPECT_RATIO_SAME_AS_PICTURE = 8,
-+ ACTIVE_FORMAT_ASPECT_RATIO_4_3 = 9,
-+ ACTIVE_FORMAT_ASPECT_RATIO_16_9 = 0XA,
-+ ACTIVE_FORMAT_ASPECT_RATIO_14_9 = 0XB
-+};
-+
-+/* RGB quantization range */
-+enum rgb_quantization_range {
-+ RGB_QUANTIZATION_DEFAULT_RANGE = 0,
-+ RGB_QUANTIZATION_LIMITED_RANGE = 1,
-+ RGB_QUANTIZATION_FULL_RANGE = 2,
-+ RGB_QUANTIZATION_RESERVED = 3
-+};
-+
-+/* YYC quantization range */
-+enum yyc_quantization_range {
-+ YYC_QUANTIZATION_LIMITED_RANGE = 0,
-+ YYC_QUANTIZATION_FULL_RANGE = 1,
-+ YYC_QUANTIZATION_RESERVED2 = 2,
-+ YYC_QUANTIZATION_RESERVED3 = 3
-+};
-+
-+/* Rotation capability */
-+struct rotation_capability {
-+ bool ROTATION_ANGLE_0_CAP:1;
-+ bool ROTATION_ANGLE_90_CAP:1;
-+ bool ROTATION_ANGLE_180_CAP:1;
-+ bool ROTATION_ANGLE_270_CAP:1;
-+};
-+
-+/* Underscan position and size */
-+struct ds_underscan_desc {
-+ uint32_t x;
-+ uint32_t y;
-+ uint32_t width;
-+ uint32_t height;
-+};
-+
-+/* View, timing and other mode related information */
-+struct path_mode {
-+ struct view view;
-+ struct rect_position view_position;
-+ enum view_3d_format view_3d_format;
-+ const struct dc_mode_timing *mode_timing;
-+ enum scaling_transformation scaling;
-+ enum pixel_format pixel_format;
-+ uint32_t display_path_index;
-+ enum tiling_mode tiling_mode;
-+ enum dc_rotation_angle rotation_angle;
-+ bool is_tiling_rotated;
-+ struct rotation_capability rotation_capability;
-+};
-+
-+struct hdmi_info_frame_header {
-+ uint8_t info_frame_type;
-+ uint8_t version;
-+ uint8_t length;
-+};
-+
-+#pragma pack(push)
-+#pragma pack(1)
-+struct info_packet_raw_data {
-+ uint8_t hb0;
-+ uint8_t hb1;
-+ uint8_t hb2;
-+ uint8_t sb[28]; /* sb0~sb27 */
-+};
-+
-+union hdmi_info_packet {
-+ struct avi_info_frame {
-+ struct hdmi_info_frame_header header;
-+
-+ uint8_t CHECK_SUM:8;
-+
-+ uint8_t S0_S1:2;
-+ uint8_t B0_B1:2;
-+ uint8_t A0:1;
-+ uint8_t Y0_Y1_Y2:3;
-+
-+ uint8_t R0_R3:4;
-+ uint8_t M0_M1:2;
-+ uint8_t C0_C1:2;
-+
-+ uint8_t SC0_SC1:2;
-+ uint8_t Q0_Q1:2;
-+ uint8_t EC0_EC2:3;
-+ uint8_t ITC:1;
-+
-+ uint8_t VIC0_VIC7:8;
-+
-+ uint8_t PR0_PR3:4;
-+ uint8_t CN0_CN1:2;
-+ uint8_t YQ0_YQ1:2;
-+
-+ uint16_t bar_top;
-+ uint16_t bar_bottom;
-+ uint16_t bar_left;
-+ uint16_t bar_right;
-+
-+ uint8_t reserved[14];
-+ } bits;
-+
-+ struct info_packet_raw_data packet_raw_data;
-+};
-+
-+struct info_packet {
-+ enum info_frame_flag flags;
-+ union hdmi_info_packet info_packet_hdmi;
-+};
-+
-+struct info_frame {
-+ struct info_packet avi_info_packet;
-+ struct info_packet gamut_packet;
-+ struct info_packet vendor_info_packet;
-+ struct info_packet spd_info_packet;
-+};
-+
-+
-+/* Adjustment parameter */
-+struct adjustment_parameters {
-+ enum adjustment_par_type type;
-+ struct {
-+ enum adjustment_id ajd_id;
-+ enum hw_adjustment_id adj_id_hw;
-+ } timings;
-+};
-+
-+/* Parameters for adjustments*/
-+struct adjustment_params {
-+ enum adjustment_action action;
-+ struct adjustment_parameters params;
-+ const struct display_path *affected_path;
-+};
-+
-+#pragma pack(pop)
-+
-+#endif /* __DAL_SET_MODE_TYPES_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/signal_types.h b/drivers/gpu/drm/amd/dal/include/signal_types.h
-new file mode 100644
-index 0000000..e95e821
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/signal_types.h
-@@ -0,0 +1,58 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_SIGNAL_TYPES_H__
-+#define __DC_SIGNAL_TYPES_H__
-+
-+enum signal_type {
-+ SIGNAL_TYPE_NONE = 0L, /* no signal */
-+ SIGNAL_TYPE_DVI_SINGLE_LINK = (1 << 0),
-+ SIGNAL_TYPE_DVI_DUAL_LINK = (1 << 1),
-+ SIGNAL_TYPE_HDMI_TYPE_A = (1 << 2),
-+ SIGNAL_TYPE_LVDS = (1 << 3),
-+ SIGNAL_TYPE_RGB = (1 << 4),
-+ SIGNAL_TYPE_DISPLAY_PORT = (1 << 5),
-+ SIGNAL_TYPE_DISPLAY_PORT_MST = (1 << 6),
-+ SIGNAL_TYPE_EDP = (1 << 7),
-+ SIGNAL_TYPE_WIRELESS = (1 << 8), /* Wireless Display */
-+
-+ SIGNAL_TYPE_COUNT = 9,
-+ SIGNAL_TYPE_ALL = (1 << SIGNAL_TYPE_COUNT) - 1
-+};
-+
-+/* help functions for signal types manipulation */
-+bool dc_is_hdmi_signal(enum signal_type signal);
-+bool dc_is_dp_sst_signal(enum signal_type signal);
-+bool dc_is_dp_signal(enum signal_type signal);
-+bool dc_is_dp_external_signal(enum signal_type signal);
-+bool dc_is_analog_signal(enum signal_type signal);
-+bool dc_is_embedded_signal(enum signal_type signal);
-+bool dc_is_dvi_signal(enum signal_type signal);
-+bool dc_is_dvi_single_link_signal(enum signal_type signal);
-+bool dc_is_dual_link_signal(enum signal_type signal);
-+bool dc_is_audio_capable_signal(enum signal_type signal);
-+bool dc_is_digital_encoder_compatible_signal(enum signal_type signal);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/stream_encoder_types.h b/drivers/gpu/drm/amd/dal/include/stream_encoder_types.h
-new file mode 100644
-index 0000000..0d3e67c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/stream_encoder_types.h
-@@ -0,0 +1,16 @@
-+/*
-+ * stream_encoder_types.h
-+ *
-+ */
-+#include "encoder_interface.h"
-+
-+#ifndef STREAM_ENCODER_TYPES_H_
-+#define STREAM_ENCODER_TYPES_H_
-+
-+struct stream_encoder {
-+ enum engine_id id;
-+ struct adapter_service *adapter_service;
-+ struct dc_context *ctx;
-+};
-+
-+#endif /* STREAM_ENCODER_TYPES_H_ */
-diff --git a/drivers/gpu/drm/amd/dal/include/timing_generator_types.h b/drivers/gpu/drm/amd/dal/include/timing_generator_types.h
-new file mode 100644
-index 0000000..9c4d92d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/timing_generator_types.h
-@@ -0,0 +1,150 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_TIMING_GENERATOR_TYPES_H__
-+#define __DAL_TIMING_GENERATOR_TYPES_H__
-+
-+#include "include/grph_csc_types.h"
-+
-+/**
-+ * These parameters are required as input when doing blanking/Unblanking
-+*/
-+struct crtc_black_color {
-+ uint32_t black_color_r_cr;
-+ uint32_t black_color_g_y;
-+ uint32_t black_color_b_cb;
-+};
-+
-+/* Contains CRTC vertical/horizontal pixel counters */
-+struct crtc_position {
-+ uint32_t vertical_count;
-+ uint32_t horizontal_count;
-+ uint32_t nominal_vcount;
-+};
-+
-+/*
-+ * Parameters to enable/disable stereo 3D mode on CRTC
-+ * - rightEyePolarity: if true, '0' means left eye image and '1' means right
-+ * eye image.
-+ * if false, '0' means right eye image and '1' means left eye image
-+ * - framePacked: true when HDMI 1.4a FramePacking 3D format
-+ * enabled/disabled
-+ */
-+struct crtc_stereo_parameters {
-+ uint8_t PROGRAM_STEREO:1;
-+ uint8_t PROGRAM_POLARITY:1;
-+ uint8_t RIGHT_EYE_POLARITY:1;
-+ uint8_t FRAME_PACKED:1;
-+};
-+
-+struct crtc_stereo_status {
-+ uint8_t ENABLED:1;
-+ uint8_t CURRENT_FRAME_IS_RIGHT_EYE:1;
-+ uint8_t CURRENT_FRAME_IS_ODD_FIELD:1;
-+ uint8_t FRAME_PACKED:1;
-+ uint8_t PENDING_RESET:1;
-+};
-+
-+enum dcp_gsl_purpose {
-+ DCP_GSL_PURPOSE_SURFACE_FLIP = 0,
-+ DCP_GSL_PURPOSE_STEREO3D_PHASE,
-+ DCP_GSL_PURPOSE_UNDEFINED
-+};
-+
-+struct dcp_gsl_params {
-+ enum sync_source gsl_group;
-+ enum dcp_gsl_purpose gsl_purpose;
-+ bool timing_server;
-+ bool overlay_present;
-+ bool gsl_paused;
-+};
-+
-+struct vbi_end_signal_setup {
-+ uint32_t minimum_interval_in_us; /* microseconds */
-+ uint32_t pixel_clock; /* in KHz */
-+ bool scaler_enabled;
-+ bool interlace;
-+ uint32_t src_height;
-+ uint32_t overscan_top;
-+ uint32_t overscan_bottom;
-+ uint32_t v_total;
-+ uint32_t v_addressable;
-+ uint32_t h_total;
-+};
-+
-+#define LEFT_EYE_3D_PRIMARY_SURFACE 1
-+#define RIGHT_EYE_3D_PRIMARY_SURFACE 0
-+
-+enum test_pattern_dyn_range {
-+ TEST_PATTERN_DYN_RANGE_VESA = 0,
-+ TEST_PATTERN_DYN_RANGE_CEA
-+};
-+
-+enum test_pattern_mode {
-+ TEST_PATTERN_MODE_COLORSQUARES_RGB = 0,
-+ TEST_PATTERN_MODE_COLORSQUARES_YCBCR601,
-+ TEST_PATTERN_MODE_COLORSQUARES_YCBCR709,
-+ TEST_PATTERN_MODE_VERTICALBARS,
-+ TEST_PATTERN_MODE_HORIZONTALBARS,
-+ TEST_PATTERN_MODE_SINGLERAMP_RGB,
-+ TEST_PATTERN_MODE_DUALRAMP_RGB
-+};
-+
-+enum test_pattern_color_format {
-+ TEST_PATTERN_COLOR_FORMAT_BPC_6 = 0,
-+ TEST_PATTERN_COLOR_FORMAT_BPC_8,
-+ TEST_PATTERN_COLOR_FORMAT_BPC_10,
-+ TEST_PATTERN_COLOR_FORMAT_BPC_12
-+};
-+
-+enum controller_dp_test_pattern {
-+ CONTROLLER_DP_TEST_PATTERN_D102 = 0,
-+ CONTROLLER_DP_TEST_PATTERN_SYMBOLERROR,
-+ CONTROLLER_DP_TEST_PATTERN_PRBS7,
-+ CONTROLLER_DP_TEST_PATTERN_COLORSQUARES,
-+ CONTROLLER_DP_TEST_PATTERN_VERTICALBARS,
-+ CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS,
-+ CONTROLLER_DP_TEST_PATTERN_COLORRAMP,
-+ CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
-+ CONTROLLER_DP_TEST_PATTERN_RESERVED_8,
-+ CONTROLLER_DP_TEST_PATTERN_RESERVED_9,
-+ CONTROLLER_DP_TEST_PATTERN_RESERVED_A,
-+ CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA
-+};
-+
-+struct timing_generator {
-+ uint32_t *regs;
-+ struct bios_parser *bp;
-+ enum controller_id controller_id;
-+ struct dc_context *ctx;
-+ uint32_t max_h_total;
-+ uint32_t max_v_total;
-+
-+ uint32_t min_h_blank;
-+ uint32_t min_h_front_porch;
-+ uint32_t min_h_back_porch;
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/timing_list_query_interface.h b/drivers/gpu/drm/amd/dal/include/timing_list_query_interface.h
-new file mode 100644
-index 0000000..16e3521
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/timing_list_query_interface.h
-@@ -0,0 +1,69 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_TIMING_LIST_QUERY_INTERFACE_H__
-+#define __DAL_TIMING_LIST_QUERY_INTERFACE_H__
-+
-+/* External dependencies */
-+#include "include/dcs_interface.h"
-+
-+/* Forward declarations */
-+struct dal;
-+struct dal_timing_list_query;
-+
-+enum timing_support_level {
-+ TIMING_SUPPORT_LEVEL_UNDEFINED,
-+ /* assumed to be guaranteed supported by display,
-+ * usually one timing is marked as native */
-+ TIMING_SUPPORT_LEVEL_NATIVE,
-+ /* user wants DAL to drive this timing as if Display supports it */
-+ TIMING_SUPPORT_LEVEL_GUARANTEED,
-+ /* user wants DAL to drive this timing even if display
-+ * may not support it */
-+ TIMING_SUPPORT_LEVEL_NOT_GUARANTEED
-+};
-+
-+struct timing_list_query_init_data {
-+ struct dal *dal; /* an instance of DAL */
-+ struct timing_service *timing_srv;
-+ struct dcs *dcs;
-+ uint32_t display_index;
-+};
-+
-+struct dal_timing_list_query *dal_timing_list_query_create(
-+ struct timing_list_query_init_data *init_data);
-+
-+void dal_timing_list_query_destroy(struct dal_timing_list_query **tlsq);
-+
-+/* Get count of mode timings in the list. */
-+uint32_t dal_timing_list_query_get_mode_timing_count(
-+ const struct dal_timing_list_query *tlsq);
-+
-+const struct dc_mode_timing *dal_timing_list_query_get_mode_timing_at_index(
-+ const struct dal_timing_list_query *tlsq,
-+ uint32_t index);
-+
-+
-+#endif /* __DAL_TIMING_LIST_QUERY_INTERFACE_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/vector.h b/drivers/gpu/drm/amd/dal/include/vector.h
-new file mode 100644
-index 0000000..8233b7c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/vector.h
-@@ -0,0 +1,150 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_VECTOR_H__
-+#define __DAL_VECTOR_H__
-+
-+struct vector {
-+ uint8_t *container;
-+ uint32_t struct_size;
-+ uint32_t count;
-+ uint32_t capacity;
-+ struct dc_context *ctx;
-+};
-+
-+bool dal_vector_construct(
-+ struct vector *vector,
-+ struct dc_context *ctx,
-+ uint32_t capacity,
-+ uint32_t struct_size);
-+
-+struct vector *dal_vector_create(
-+ struct dc_context *ctx,
-+ uint32_t capacity,
-+ uint32_t struct_size);
-+
-+/* 'initial_value' is optional. If initial_value not supplied,
-+ * each "structure" in the vector will contain zeros by default. */
-+struct vector *dal_vector_presized_create(
-+ struct dc_context *ctx,
-+ uint32_t size,
-+ void *initial_value,
-+ uint32_t struct_size);
-+
-+void dal_vector_destruct(
-+ struct vector *vector);
-+
-+void dal_vector_destroy(
-+ struct vector **vector);
-+
-+uint32_t dal_vector_get_count(
-+ const struct vector *vector);
-+
-+/* dal_vector_insert_at
-+ * reallocate container if necessary
-+ * then shell items at right and insert
-+ * return if the container modified
-+ * do not check that index belongs to container
-+ * since the function is private and index is going to be calculated
-+ * either with by function or as get_count+1 */
-+bool dal_vector_insert_at(
-+ struct vector *vector,
-+ const void *what,
-+ uint32_t position);
-+
-+bool dal_vector_append(
-+ struct vector *vector,
-+ const void *item);
-+
-+/* operator[] */
-+void *dal_vector_at_index(
-+ const struct vector *vector,
-+ uint32_t index);
-+
-+void dal_vector_set_at_index(
-+ const struct vector *vector,
-+ const void *what,
-+ uint32_t index);
-+
-+/* create a clone (copy) of a vector */
-+struct vector *dal_vector_clone(
-+ const struct vector *vector_other);
-+
-+/* dal_vector_remove_at_index
-+ * Shifts elements on the right from remove position to the left,
-+ * removing an element at position by overwrite means*/
-+bool dal_vector_remove_at_index(
-+ struct vector *vector,
-+ uint32_t index);
-+
-+uint32_t dal_vector_capacity(const struct vector *vector);
-+
-+bool dal_vector_reserve(struct vector *vector, uint32_t capacity);
-+
-+void dal_vector_clear(struct vector *vector);
-+
-+/***************************************************************************
-+ * Macro definitions of TYPE-SAFE versions of vector set/get functions.
-+ ***************************************************************************/
-+
-+#define DAL_VECTOR_INSERT_AT(vector_type, type_t) \
-+ static bool vector_type##_vector_insert_at( \
-+ struct vector *vector, \
-+ type_t what, \
-+ uint32_t position) \
-+{ \
-+ return dal_vector_insert_at(vector, what, position); \
-+}
-+
-+#define DAL_VECTOR_APPEND(vector_type, type_t) \
-+ static bool vector_type##_vector_append( \
-+ struct vector *vector, \
-+ type_t item) \
-+{ \
-+ return dal_vector_append(vector, item); \
-+}
-+
-+/* Note: "type_t" is the ONLY token accepted by "checkpatch.pl" and by
-+ * "checkcommit" as *return type*.
-+ * For uniformity reasons "type_t" is used for all type-safe macro
-+ * definitions here. */
-+#define DAL_VECTOR_AT_INDEX(vector_type, type_t) \
-+ static type_t vector_type##_vector_at_index( \
-+ const struct vector *vector, \
-+ uint32_t index) \
-+{ \
-+ return dal_vector_at_index(vector, index); \
-+}
-+
-+#define DAL_VECTOR_SET_AT_INDEX(vector_type, type_t) \
-+ static void vector_type##_vector_set_at_index( \
-+ const struct vector *vector, \
-+ type_t what, \
-+ uint32_t index) \
-+{ \
-+ dal_vector_set_at_index(vector, what, index); \
-+}
-+
-+#endif /* __DAL_VECTOR_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/include/video_csc_types.h b/drivers/gpu/drm/amd/dal/include/video_csc_types.h
-new file mode 100644
-index 0000000..c229f5a
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/video_csc_types.h
-@@ -0,0 +1,135 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_VIDEO_CSC_TYPES_H__
-+#define __DAL_VIDEO_CSC_TYPES_H__
-+
-+#include "video_gamma_types.h"
-+
-+enum ovl_alpha_blending_mode {
-+ OVL_ALPHA_PER_PIXEL_GRPH_ALPHA_MODE = 0,
-+ OVL_ALPHA_PER_PIXEL_OVL_ALPHA_MODE
-+};
-+
-+enum ovl_color_space {
-+ OVL_COLOR_SPACE_UNKNOWN = 0,
-+ OVL_COLOR_SPACE_RGB,
-+ OVL_COLOR_SPACE_YUV601,
-+ OVL_COLOR_SPACE_YUV709
-+};
-+
-+enum ovl_surface_format {
-+ OVL_SURFACE_FORMAT_UNKNOWN = 0,
-+ OVL_SURFACE_FORMAT_YUY2,
-+ OVL_SURFACE_FORMAT_UYVY,
-+ OVL_SURFACE_FORMAT_RGB565,
-+ OVL_SURFACE_FORMAT_RGB555,
-+ OVL_SURFACE_FORMAT_RGB32,
-+ OVL_SURFACE_FORMAT_YUV444,
-+ OVL_SURFACE_FORMAT_RGB32_2101010
-+};
-+
-+struct ovl_color_adjust_option {
-+ uint32_t ALLOW_OVL_RGB_ADJUST:1;
-+ uint32_t ALLOW_OVL_TEMPERATURE:1;
-+ uint32_t FULL_RANGE:1; /* 0 for limited range it'is default for YUV */
-+ uint32_t OVL_MATRIX:1;
-+ uint32_t RESERVED:28;
-+};
-+
-+struct overlay_adjust_item {
-+ int32_t adjust; /* InInteger */
-+ int32_t adjust_divider;
-+};
-+
-+enum overlay_csc_adjust_type {
-+ OVERLAY_CSC_ADJUST_TYPE_BYPASS = 0,
-+ OVERLAY_CSC_ADJUST_TYPE_HW, /* without adjustments */
-+ OVERLAY_CSC_ADJUST_TYPE_SW /* use adjustments */
-+};
-+
-+enum overlay_gamut_adjust_type {
-+ OVERLAY_GAMUT_ADJUST_TYPE_BYPASS = 0,
-+ OVERLAY_GAMUT_ADJUST_TYPE_SW /* use adjustments */
-+};
-+
-+#define TEMPERATURE_MATRIX_SIZE 9
-+#define MAXTRIX_SIZE TEMPERATURE_MAXTRIX_SIZE
-+#define MAXTRIX_SIZE_WITH_OFFSET 12
-+
-+/* overlay adjustment input */
-+union ovl_csc_flag {
-+ uint32_t u_all;
-+ struct {
-+ uint32_t CONFIG_IS_CHANGED:1;
-+ uint32_t RESERVED:31;
-+ } bits;
-+};
-+
-+struct ovl_csc_adjustment {
-+ enum ovl_color_space ovl_cs;
-+ struct ovl_color_adjust_option ovl_option;
-+ enum dc_color_depth display_color_depth;
-+ uint32_t lb_color_depth;
-+ enum pixel_format desktop_surface_pixel_format;
-+ enum ovl_surface_format ovl_sf;
-+ /* API adjustment */
-+ struct overlay_adjust_item overlay_brightness;
-+ struct overlay_adjust_item overlay_gamma;
-+ struct overlay_adjust_item overlay_contrast;
-+ struct overlay_adjust_item overlay_saturation;
-+ struct overlay_adjust_item overlay_hue; /* unit in degree from API. */
-+ int32_t f_temperature[TEMPERATURE_MATRIX_SIZE];
-+ uint32_t temperature_divider;
-+ /* OEM/Application matrix related. */
-+ int32_t matrix[MAXTRIX_SIZE_WITH_OFFSET];
-+ uint32_t matrix_divider;
-+
-+ /* DCE50 parameters */
-+ struct regamma_lut regamma;
-+ enum overlay_gamma_adjust adjust_gamma_type;
-+ enum overlay_csc_adjust_type adjust_csc_type;
-+ enum overlay_gamut_adjust_type adjust_gamut_type;
-+ union ovl_csc_flag flag;
-+
-+};
-+
-+enum ovl_csc_adjust_item {
-+ OVERLAY_BRIGHTNESS = 0,
-+ OVERLAY_GAMMA,
-+ OVERLAY_CONTRAST,
-+ OVERLAY_SATURATION,
-+ OVERLAY_HUE,
-+ OVERLAY_ALPHA,
-+ OVERLAY_ALPHA_PER_PIX,
-+ OVERLAY_COLOR_TEMPERATURE
-+};
-+
-+struct input_csc_matrix {
-+ enum color_space color_space;
-+ uint16_t regval[12];
-+};
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/include/video_gamma_types.h b/drivers/gpu/drm/amd/dal/include/video_gamma_types.h
-new file mode 100644
-index 0000000..dc294b6
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/include/video_gamma_types.h
-@@ -0,0 +1,56 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_VIDEO_GAMMA_TYPES_H__
-+#define __DAL_VIDEO_GAMMA_TYPES_H__
-+
-+#include "set_mode_types.h"
-+
-+enum overlay_gamma_adjust {
-+ OVERLAY_GAMMA_ADJUST_BYPASS,
-+ OVERLAY_GAMMA_ADJUST_HW, /* without adjustments */
-+ OVERLAY_GAMMA_ADJUST_SW /* use adjustments */
-+
-+};
-+
-+union video_gamma_flag {
-+ struct {
-+ uint32_t CONFIG_IS_CHANGED:1;
-+ uint32_t RESERVED:31;
-+ } bits;
-+ uint32_t u_all;
-+};
-+
-+struct overlay_gamma_parameters {
-+ union video_gamma_flag flag;
-+ int32_t ovl_gamma_cont;
-+ enum overlay_gamma_adjust adjust_type;
-+ enum pixel_format desktop_surface;
-+ struct regamma_lut regamma;
-+
-+ /* here we grow with parameters if necessary */
-+};
-+
-+#endif
---
-2.7.4
-