aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0803-drm-amd-dal-Adding-Hawaii-and-Bonaire-support-to-DAL.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0803-drm-amd-dal-Adding-Hawaii-and-Bonaire-support-to-DAL.patch')
-rw-r--r--common/recipes-kernel/linux/files/0803-drm-amd-dal-Adding-Hawaii-and-Bonaire-support-to-DAL.patch19970
1 files changed, 0 insertions, 19970 deletions
diff --git a/common/recipes-kernel/linux/files/0803-drm-amd-dal-Adding-Hawaii-and-Bonaire-support-to-DAL.patch b/common/recipes-kernel/linux/files/0803-drm-amd-dal-Adding-Hawaii-and-Bonaire-support-to-DAL.patch
deleted file mode 100644
index 0a8091e8..00000000
--- a/common/recipes-kernel/linux/files/0803-drm-amd-dal-Adding-Hawaii-and-Bonaire-support-to-DAL.patch
+++ /dev/null
@@ -1,19970 +0,0 @@
-From f916c629a50d432a9b9b46d859ddbc93e2ca1973 Mon Sep 17 00:00:00 2001
-From: Harry Wentland <harry.wentland@amd.com>
-Date: Wed, 17 Feb 2016 10:41:59 -0500
-Subject: [PATCH 0803/1110] drm/amd/dal: Adding Hawaii and Bonaire support to
- DAL
-
-Signed-off-by: Harry Wentland <harry.wentland@amd.com>
-Acked-by: Jordan Lazare <Jordan.Lazare@amd.com>
----
- drivers/gpu/drm/amd/dal/Kconfig | 17 +-
- drivers/gpu/drm/amd/dal/dc/Makefile | 4 +
- drivers/gpu/drm/amd/dal/dc/adapter/Makefile | 8 +
- .../gpu/drm/amd/dal/dc/adapter/adapter_service.c | 13 +
- .../adapter/dce80/hw_ctx_adapter_service_dce80.c | 322 ++++
- .../adapter/dce80/hw_ctx_adapter_service_dce80.h | 40 +
- .../gpu/drm/amd/dal/dc/asic_capability/Makefile | 13 +
- .../amd/dal/dc/asic_capability/asic_capability.c | 8 +
- .../dc/asic_capability/hawaii_asic_capability.c | 151 ++
- .../dc/asic_capability/hawaii_asic_capability.h | 37 +
- drivers/gpu/drm/amd/dal/dc/audio/Makefile | 12 +
- drivers/gpu/drm/amd/dal/dc/audio/audio_base.c | 9 +
- .../gpu/drm/amd/dal/dc/audio/dce80/audio_dce80.c | 434 +++++
- .../gpu/drm/amd/dal/dc/audio/dce80/audio_dce80.h | 41 +
- .../amd/dal/dc/audio/dce80/hw_ctx_audio_dce80.c | 1926 ++++++++++++++++++++
- .../amd/dal/dc/audio/dce80/hw_ctx_audio_dce80.h | 75 +
- drivers/gpu/drm/amd/dal/dc/bios/Makefile | 13 +
- .../gpu/drm/amd/dal/dc/bios/bios_parser_helper.c | 6 +-
- .../gpu/drm/amd/dal/dc/bios/bios_parser_helper.h | 4 +
- .../gpu/drm/amd/dal/dc/bios/command_table_helper.c | 5 +
- .../gpu/drm/amd/dal/dc/bios/command_table_helper.h | 3 +
- .../dal/dc/bios/dce80/bios_parser_helper_dce80.c | 773 ++++++++
- .../dal/dc/bios/dce80/bios_parser_helper_dce80.h | 33 +
- .../dal/dc/bios/dce80/command_table_helper_dce80.c | 355 ++++
- .../dal/dc/bios/dce80/command_table_helper_dce80.h | 33 +
- drivers/gpu/drm/amd/dal/dc/core/dc_hw_sequencer.c | 7 +
- drivers/gpu/drm/amd/dal/dc/core/dc_resource.c | 3 +
- drivers/gpu/drm/amd/dal/dc/dce80/Makefile | 17 +
- .../gpu/drm/amd/dal/dc/dce80/dce80_compressor.c | 867 +++++++++
- .../gpu/drm/amd/dal/dc/dce80/dce80_compressor.h | 84 +
- .../gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.c | 308 ++++
- .../gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.h | 36 +
- drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp.c | 64 +
- drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp.h | 49 +
- drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp_gamma.c | 85 +
- .../gpu/drm/amd/dal/dc/dce80/dce80_link_encoder.c | 329 ++++
- .../gpu/drm/amd/dal/dc/dce80/dce80_link_encoder.h | 39 +
- drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c | 217 +++
- drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.h | 41 +
- drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp.c | 141 ++
- drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp.h | 130 ++
- drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp_csc.c | 905 +++++++++
- .../gpu/drm/amd/dal/dc/dce80/dce80_opp_formatter.c | 577 ++++++
- .../gpu/drm/amd/dal/dc/dce80/dce80_opp_regamma.c | 546 ++++++
- drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c | 1267 +++++++++++++
- drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.h | 42 +
- .../drm/amd/dal/dc/dce80/dce80_stream_encoder.c | 1104 +++++++++++
- .../drm/amd/dal/dc/dce80/dce80_stream_encoder.h | 85 +
- .../drm/amd/dal/dc/dce80/dce80_timing_generator.c | 241 +++
- .../drm/amd/dal/dc/dce80/dce80_timing_generator.h | 49 +
- drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform.c | 91 +
- drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform.h | 87 +
- .../amd/dal/dc/dce80/dce80_transform_bit_depth.c | 841 +++++++++
- .../amd/dal/dc/dce80/dce80_transform_bit_depth.h | 51 +
- .../drm/amd/dal/dc/dce80/dce80_transform_gamut.c | 297 +++
- .../gpu/drm/amd/dal/dc/dce80/dce80_transform_scl.c | 814 +++++++++
- drivers/gpu/drm/amd/dal/dc/gpio/Makefile | 12 +
- .../gpu/drm/amd/dal/dc/gpio/dce80/hw_ddc_dce80.c | 893 +++++++++
- .../gpu/drm/amd/dal/dc/gpio/dce80/hw_ddc_dce80.h | 46 +
- .../drm/amd/dal/dc/gpio/dce80/hw_factory_dce80.c | 78 +
- .../drm/amd/dal/dc/gpio/dce80/hw_factory_dce80.h | 32 +
- .../gpu/drm/amd/dal/dc/gpio/dce80/hw_hpd_dce80.c | 378 ++++
- .../gpu/drm/amd/dal/dc/gpio/dce80/hw_hpd_dce80.h | 44 +
- .../drm/amd/dal/dc/gpio/dce80/hw_translate_dce80.c | 424 +++++
- .../drm/amd/dal/dc/gpio/dce80/hw_translate_dce80.h | 32 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c | 9 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c | 10 +-
- drivers/gpu/drm/amd/dal/dc/gpu/Makefile | 12 +
- .../amd/dal/dc/gpu/dce80/dc_clock_gating_dce80.c | 52 +
- .../amd/dal/dc/gpu/dce80/dc_clock_gating_dce80.h | 31 +
- .../drm/amd/dal/dc/gpu/dce80/display_clock_dce80.c | 925 ++++++++++
- .../drm/amd/dal/dc/gpu/dce80/display_clock_dce80.h | 58 +
- drivers/gpu/drm/amd/dal/dc/i2caux/Makefile | 11 +
- .../drm/amd/dal/dc/i2caux/dce80/aux_engine_dce80.c | 740 ++++++++
- .../drm/amd/dal/dc/i2caux/dce80/aux_engine_dce80.h | 54 +
- .../amd/dal/dc/i2caux/dce80/i2c_hw_engine_dce80.c | 901 +++++++++
- .../amd/dal/dc/i2caux/dce80/i2c_hw_engine_dce80.h | 54 +
- .../amd/dal/dc/i2caux/dce80/i2c_sw_engine_dce80.c | 187 ++
- .../amd/dal/dc/i2caux/dce80/i2c_sw_engine_dce80.h | 43 +
- .../gpu/drm/amd/dal/dc/i2caux/dce80/i2caux_dce80.c | 264 +++
- .../gpu/drm/amd/dal/dc/i2caux/dce80/i2caux_dce80.h | 39 +
- drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c | 8 +
- drivers/gpu/drm/amd/dal/dc/irq/irq_service.c | 11 +
- drivers/gpu/drm/amd/dal/include/dal_types.h | 3 +
- .../drm/amd/dal/include/display_clock_interface.h | 6 +
- 85 files changed, 19100 insertions(+), 6 deletions(-)
- create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/dce80/hw_ctx_adapter_service_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/dce80/hw_ctx_adapter_service_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/asic_capability/hawaii_asic_capability.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/asic_capability/hawaii_asic_capability.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/dce80/audio_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/dce80/audio_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/dce80/hw_ctx_audio_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/dce80/hw_ctx_audio_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/dce80/bios_parser_helper_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/dce80/bios_parser_helper_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/dce80/command_table_helper_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/dce80/command_table_helper_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_compressor.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_compressor.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp_gamma.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_link_encoder.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_link_encoder.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp_csc.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp_formatter.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp_regamma.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_stream_encoder.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_stream_encoder.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_timing_generator.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_timing_generator.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_bit_depth.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_bit_depth.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_gamut.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_scl.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_ddc_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_ddc_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_factory_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_factory_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_hpd_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_hpd_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_translate_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_translate_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce80/dc_clock_gating_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce80/dc_clock_gating_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce80/display_clock_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce80/display_clock_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce80/aux_engine_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce80/aux_engine_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_hw_engine_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_hw_engine_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_sw_engine_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_sw_engine_dce80.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2caux_dce80.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2caux_dce80.h
-
-diff --git a/drivers/gpu/drm/amd/dal/Kconfig b/drivers/gpu/drm/amd/dal/Kconfig
-index 0dc6f86..b108756 100644
---- a/drivers/gpu/drm/amd/dal/Kconfig
-+++ b/drivers/gpu/drm/amd/dal/Kconfig
-@@ -19,14 +19,14 @@ config DRM_AMD_DAL_VBIOS_PRESENT
- x86 platforms and there is a VBIOS
- present in the system
-
--config DRM_AMD_DAL_DCE11_0
-- bool "Carrizo family"
-+config DRM_AMD_DAL_DCE8_0
-+ bool "CI family"
- depends on DRM_AMD_DAL
- help
- Choose this option
- if you want to have
-- CZ family
-- for display engine
-+ CI family
-+ for display engine.
-
- config DRM_AMD_DAL_DCE10_0
- bool "VI family"
-@@ -37,6 +37,15 @@ config DRM_AMD_DAL_DCE10_0
- VI family for display
- engine.
-
-+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
-diff --git a/drivers/gpu/drm/amd/dal/dc/Makefile b/drivers/gpu/drm/amd/dal/dc/Makefile
-index aed26ee..5112ec9 100644
---- a/drivers/gpu/drm/amd/dal/dc/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/Makefile
-@@ -13,6 +13,10 @@ ifdef CONFIG_DRM_AMD_DAL_DCE10_0
- DC_LIBS += dce100
- endif
-
-+ifdef CONFIG_DRM_AMD_DAL_DCE8_0
-+DC_LIBS += dce80
-+endif
-+
- AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DAL_PATH)/dc/,$(DC_LIBS)))
-
- include $(AMD_DC)
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/Makefile b/drivers/gpu/drm/amd/dal/dc/adapter/Makefile
-index 2c6ca7a..db1f0e8 100644
---- a/drivers/gpu/drm/amd/dal/dc/adapter/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/Makefile
-@@ -8,6 +8,14 @@ AMD_DAL_ADAPTER = $(addprefix $(AMDDALPATH)/dc/adapter/,$(ADAPTER))
-
- AMD_DAL_FILES += $(AMD_DAL_ADAPTER)
-
-+###############################################################################
-+# DCE 8x
-+###############################################################################
-+
-+ifdef CONFIG_DRM_AMD_DAL_DCE8_0
-+AMD_DAL_FILES += $(AMDDALPATH)/dc/adapter/dce80/hw_ctx_adapter_service_dce80.o
-+endif
-+
-
- ###############################################################################
- # DCE 11x
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c
-index dd2f931..f914a8c 100644
---- a/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c
-@@ -41,6 +41,10 @@
-
- #include "atom.h"
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+#include "dce80/hw_ctx_adapter_service_dce80.h"
-+#endif
-+
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
- #include "dce110/hw_ctx_adapter_service_dce110.h"
- #endif
-@@ -665,6 +669,10 @@ static struct hw_ctx_adapter_service *create_hw_ctx(
- return dal_adapter_service_create_hw_ctx_diag(ctx);
-
- switch (dce_version) {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ case DCE_VERSION_8_0:
-+ return dal_adapter_service_create_hw_ctx_dce80(ctx);
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- case DCE_VERSION_10_0:
- return dal_adapter_service_create_hw_ctx_dce110(ctx);
-@@ -903,6 +911,11 @@ enum dce_version dal_adapter_service_get_dce_version(
- uint32_t version = as->asic_cap->data[ASIC_DATA_DCE_VERSION];
-
- switch (version) {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ case 0x80:
-+ /* CI Bonaire */
-+ return DCE_VERSION_8_0;
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- case 0x100:
- return DCE_VERSION_10_0;
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/dce80/hw_ctx_adapter_service_dce80.c b/drivers/gpu/drm/amd/dal/dc/adapter/dce80/hw_ctx_adapter_service_dce80.c
-new file mode 100644
-index 0000000..9d6505c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/dce80/hw_ctx_adapter_service_dce80.c
-@@ -0,0 +1,322 @@
-+/*
-+ * 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 "dm_services.h"
-+#include "include/adapter_service_types.h"
-+#include "include/grph_object_id.h"
-+#include "../hw_ctx_adapter_service.h"
-+
-+#include "hw_ctx_adapter_service_dce80.h"
-+
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+#ifndef mmCC_DC_HDMI_STRAPS
-+#define mmCC_DC_HDMI_STRAPS 0x1918
-+#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
-+
-+enum {
-+ MAX_NUMBER_OF_AUDIO_PINS = 7
-+};
-+
-+static const uint32_t audio_index_reg_offset[] = {
-+ mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ mmAZF0ENDPOINT4_AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ mmAZF0ENDPOINT5_AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ /* TR, BN has 7 audio endpoints but 6 DIGs */
-+ mmAZF0ENDPOINT6_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,
-+ mmAZF0ENDPOINT4_AZALIA_F0_CODEC_ENDPOINT_DATA,
-+ mmAZF0ENDPOINT5_AZALIA_F0_CODEC_ENDPOINT_DATA,
-+ mmAZF0ENDPOINT6_AZALIA_F0_CODEC_ENDPOINT_DATA
-+};
-+
-+static const struct graphics_object_id invalid_go = {
-+ 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN
-+};
-+
-+#define FROM_HW_CTX(ptr) \
-+ container_of((ptr), struct hw_ctx_adapter_service_dce80, base)
-+
-+static void destruct(
-+ struct hw_ctx_adapter_service_dce80 *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_dce80 *hw_ctx =
-+ FROM_HW_CTX(ptr);
-+
-+ destruct(hw_ctx);
-+
-+ dm_free(ptr->ctx, hw_ctx);
-+}
-+
-+static uint32_t get_number_of_connected_audio_endpoints_multistream(
-+ struct hw_ctx_adapter_service *hw_ctx)
-+{
-+ struct dc_context *ctx = hw_ctx->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);
-+
-+ dm_write_reg(ctx, audio_index_reg_offset[i], value);
-+
-+ value = 0;
-+ value = dm_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;
-+}
-+
-+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 = dm_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);
-+
-+ /* unexpected value */
-+ ASSERT_CRITICAL(false);
-+ return field;
-+}
-+
-+static bool power_up(
-+ struct hw_ctx_adapter_service *hw_ctx)
-+{
-+ uint32_t value = 0;
-+ uint32_t field = 0;
-+
-+ value = dm_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 = dm_read_reg(
-+ hw_ctx->ctx, mmDC_PINSTRAPS);
-+ field = get_reg_field_value(
-+ value,
-+ DC_PINSTRAPS,
-+ DC_PINSTRAPS_AUDIO);
-+ }
-+
-+ /* get the number of connected audio endpoints */
-+ FROM_HW_CTX(hw_ctx)->number_of_connected_audio_endpoints =
-+ get_number_of_connected_audio_endpoints(hw_ctx);
-+
-+ return true;
-+}
-+
-+static struct graphics_object_id enum_fake_path_resource(
-+ const struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t index)
-+{
-+ if (index == 0)
-+ return dal_graphics_object_id_init(
-+ CONNECTOR_ID_VGA,
-+ ENUM_ID_1,
-+ OBJECT_TYPE_CONNECTOR);
-+ else if (index == 1)
-+ return dal_graphics_object_id_init(
-+ ENCODER_ID_INTERNAL_KLDSCP_DAC1,
-+ ENUM_ID_1,
-+ OBJECT_TYPE_ENCODER);
-+ else
-+ 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)
-+{
-+ uint32_t number_of_connected_audio_endpoints =
-+ FROM_HW_CTX(hw_ctx)->number_of_connected_audio_endpoints;
-+
-+ if (index >= number_of_connected_audio_endpoints)
-+ return invalid_go;
-+ else
-+ return dal_graphics_object_id_init(
-+ AUDIO_ID_INTERNAL_AZALIA,
-+ (enum object_enum_id)(index + 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)
-+{
-+ uint32_t number_of_connected_audio_endpoints =
-+ FROM_HW_CTX(hw_ctx)->number_of_connected_audio_endpoints;
-+
-+ uint32_t co_func_audio_endpoint = number_of_connected_audio_endpoints;
-+ struct dc_context *ctx = hw_ctx->ctx;
-+
-+ if (co_func_audio_endpoint > number_of_audio_capable_display_path)
-+ co_func_audio_endpoint = number_of_audio_capable_display_path;
-+
-+ if (co_func_audio_endpoint > number_of_controllers)
-+ co_func_audio_endpoint = number_of_controllers;
-+
-+ if (co_func_audio_endpoint < number_of_connected_audio_endpoints) {
-+ const uint32_t addr = mmCC_RCU_DC_AUDIO_PORT_CONNECTIVITY;
-+
-+ uint32_t value;
-+
-+ value = dm_read_reg(ctx, addr);
-+
-+ set_reg_field_value(value,
-+ 7 - co_func_audio_endpoint,
-+ CC_RCU_DC_AUDIO_PORT_CONNECTIVITY,
-+ PORT_CONNECTIVITY);
-+ set_reg_field_value(value,
-+ 1,
-+ CC_RCU_DC_AUDIO_PORT_CONNECTIVITY,
-+ PORT_CONNECTIVITY_OVERRIDE_ENABLE);
-+
-+ dm_write_reg(ctx, addr, value);
-+ }
-+}
-+
-+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
-+};
-+
-+static bool construct(
-+ struct hw_ctx_adapter_service_dce80 *hw_ctx,
-+ struct dc_context *ctx)
-+{
-+ if (!dal_adapter_service_construct_hw_ctx(&hw_ctx->base, ctx)) {
-+ BREAK_TO_DEBUGGER();
-+ 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_dce80(struct dc_context *ctx)
-+{
-+ struct hw_ctx_adapter_service_dce80 *hw_ctx =
-+ dm_alloc(ctx, sizeof(struct hw_ctx_adapter_service_dce80));
-+
-+ if (!hw_ctx) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ if (construct(hw_ctx, ctx))
-+ return &hw_ctx->base;
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ dm_free(ctx, hw_ctx);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/dce80/hw_ctx_adapter_service_dce80.h b/drivers/gpu/drm/amd/dal/dc/adapter/dce80/hw_ctx_adapter_service_dce80.h
-new file mode 100644
-index 0000000..a735eaf
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/dce80/hw_ctx_adapter_service_dce80.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_DCE80_H__
-+#define __DAL_HW_CTX_ADAPTER_SERVICE_DCE80_H__
-+
-+struct hw_ctx_adapter_service_dce80 {
-+ struct hw_ctx_adapter_service base;
-+ uint32_t number_of_connected_audio_endpoints;
-+};
-+
-+struct hw_ctx_adapter_service *
-+ dal_adapter_service_create_hw_ctx_dce80(
-+ struct dc_context *ctx);
-+
-+#endif /* __DAL_HW_CTX_ADAPTER_SERVICE_DCE80_H__ */
-+
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/asic_capability/Makefile b/drivers/gpu/drm/amd/dal/dc/asic_capability/Makefile
-index 8491b38..b243542 100644
---- a/drivers/gpu/drm/amd/dal/dc/asic_capability/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/asic_capability/Makefile
-@@ -10,6 +10,19 @@ AMD_DAL_ASIC_CAPABILITY = \
- AMD_DAL_FILES += $(AMD_DAL_ASIC_CAPABILITY)
-
- ###############################################################################
-+# DCE 8x
-+###############################################################################
-+ifdef CONFIG_DRM_AMD_DAL_DCE8_0
-+ASIC_CAPABILITY_DCE80 = hawaii_asic_capability.o
-+
-+AMD_DAL_ASIC_CAPABILITY_DCE80 = \
-+ $(addprefix $(AMDDALPATH)/dc/asic_capability/,$(ASIC_CAPABILITY_DCE80))
-+
-+AMD_DAL_FILES += $(AMD_DAL_ASIC_CAPABILITY_DCE80)
-+endif
-+
-+
-+###############################################################################
- # DCE 10x
- ###############################################################################
- ifdef CONFIG_DRM_AMD_DAL_DCE10_0
-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
-index 7a905f5..69909dd 100644
---- a/drivers/gpu/drm/amd/dal/dc/asic_capability/asic_capability.c
-+++ b/drivers/gpu/drm/amd/dal/dc/asic_capability/asic_capability.c
-@@ -32,6 +32,10 @@
- #include "include/dal_types.h"
- #include "include/dal_asic_id.h"
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+#include "hawaii_asic_capability.h"
-+#endif
-+
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- #include "tonga_asic_capability.h"
- #endif
-@@ -85,6 +89,10 @@ static bool construct(
-
- switch (init->chip_family) {
- case FAMILY_CI:
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ dal_hawaii_asic_capability_create(cap, init);
-+ asic_supported = true;
-+#endif
- break;
-
- case FAMILY_KV:
-diff --git a/drivers/gpu/drm/amd/dal/dc/asic_capability/hawaii_asic_capability.c b/drivers/gpu/drm/amd/dal/dc/asic_capability/hawaii_asic_capability.c
-new file mode 100644
-index 0000000..2745ac1
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/asic_capability/hawaii_asic_capability.c
-@@ -0,0 +1,151 @@
-+/*
-+ * 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
-+ *
-+ */
-+
-+/*
-+ * Includes
-+ */
-+
-+#include "dm_services.h"
-+
-+#include "include/asic_capability_interface.h"
-+#include "include/asic_capability_types.h"
-+#include "include/dal_types.h"
-+#include "include/dal_asic_id.h"
-+#include "include/logger_interface.h"
-+#include "hawaii_asic_capability.h"
-+
-+#include "atom.h"
-+
-+#include "dce/dce_8_0_d.h"
-+#include "gmc/gmc_7_1_d.h"
-+
-+
-+/*
-+ * Sea Islands (CI) ASIC capability.
-+ *
-+ * dal_hawaii_asic_capability_create
-+ *
-+ * Create and initiate hawaii capability.
-+ */
-+void dal_hawaii_asic_capability_create(struct asic_capability *cap,
-+ struct hw_asic_id *init)
-+{
-+ uint32_t mc_seq_misc0;
-+
-+ /* ASIC data */
-+ cap->data[ASIC_DATA_CONTROLLERS_NUM] = 6;
-+ cap->data[ASIC_DATA_FUNCTIONAL_CONTROLLERS_NUM] = 6;
-+ cap->data[ASIC_DATA_DIGFE_NUM] = 6;
-+ cap->data[ASIC_DATA_LINEBUFFER_NUM] = 6;
-+ cap->data[ASIC_DATA_MAX_COFUNC_NONDP_DISPLAYS] = 2;
-+ cap->data[ASIC_DATA_MIN_DISPCLK_FOR_UNDERSCAN] = 300000;
-+
-+ cap->data[ASIC_DATA_DCE_VERSION] = 0x80; /* DCE 8.0 */
-+
-+ /* Pixel RAM is 1712 entries of 144 bits each or
-+ * in other words 246528 bits. */
-+ cap->data[ASIC_DATA_LINEBUFFER_SIZE] = 1712 * 144;
-+ cap->data[ASIC_DATA_DRAM_BANDWIDTH_EFFICIENCY] = 70;
-+ cap->data[ASIC_DATA_CLOCKSOURCES_NUM] = 3;
-+ cap->data[ASIC_DATA_MC_LATENCY] = 5000; /* units of ns */
-+
-+ /* StutterModeEnhanced; Quad DMIF Buffer */
-+ cap->data[ASIC_DATA_STUTTERMODE] = 0x2002;
-+ cap->data[ASIC_DATA_PATH_NUM_PER_DPMST_CONNECTOR] = 4;
-+ cap->data[ASIC_DATA_VIEWPORT_PIXEL_GRANULARITY] = 2;
-+
-+ /* 3 HDMI support by default */
-+ cap->data[ASIC_DATA_SUPPORTED_HDMI_CONNECTION_NUM] = 3;
-+
-+ cap->data[ASIC_DATA_DEFAULT_I2C_SPEED_IN_KHZ] = 40;
-+
-+ mc_seq_misc0 = dm_read_reg(cap->ctx, mmMC_SEQ_MISC0);
-+
-+ switch (mc_seq_misc0 & MC_MISC0__MEMORY_TYPE_MASK) {
-+ case MC_MISC0__MEMORY_TYPE__GDDR1:
-+ case MC_MISC0__MEMORY_TYPE__DDR2:
-+ case MC_MISC0__MEMORY_TYPE__DDR3:
-+ case MC_MISC0__MEMORY_TYPE__GDDR3:
-+ case MC_MISC0__MEMORY_TYPE__GDDR4:
-+ cap->data[ASIC_DATA_MEMORYTYPE_MULTIPLIER] = 2;
-+ break;
-+ case MC_MISC0__MEMORY_TYPE__GDDR5:
-+ cap->data[ASIC_DATA_MEMORYTYPE_MULTIPLIER] = 4;
-+ break;
-+ default:
-+ dal_logger_write(cap->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_MASK_ALL,
-+ "%s:Unrecognized memory type!", __func__);
-+ cap->data[ASIC_DATA_MEMORYTYPE_MULTIPLIER] = 2;
-+ break;
-+ }
-+
-+ /* ASIC stereo 3D capability */
-+ cap->stereo_3d_caps.INTERLEAVE = 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.DISPLAY_BASED_ON_WS = true;
-+
-+ /* ASIC basic capability */
-+ cap->caps.DP_MST_SUPPORTED = true;
-+ cap->caps.PANEL_SELF_REFRESH_SUPPORTED = true;
-+
-+ cap->caps.MIRABILIS_SUPPORTED = true;
-+ cap->caps.MIRABILIS_ENABLED_BY_DEFAULT = true;
-+
-+ /* Remap device tag IDs when patching VBIOS. */
-+ cap->caps.DEVICE_TAG_REMAP_SUPPORTED = true;
-+
-+ /* Report headless if no OPM attached (with MXM connectors present). */
-+ cap->caps.HEADLESS_NO_OPM_SUPPORTED = true;
-+
-+
-+ cap->caps.HPD_CHECK_FOR_EDID = true;
-+ cap->caps.NO_VCC_OFF_HPD_POLLING = true;
-+
-+ /* true will hang the system! */
-+ cap->caps.DFSBYPASS_DYNAMIC_SUPPORT = false;
-+
-+ /* Do w/a on CI A0 by default */
-+ if (init->hw_internal_rev == CI_BONAIRE_M_A0)
-+ cap->bugs.LB_WA_IS_SUPPORTED = true;
-+
-+ /* Apply MC Tuning for Hawaii */
-+ if (ASIC_REV_IS_HAWAII_P(init->hw_internal_rev))
-+ cap->caps.NEED_MC_TUNING = true;
-+
-+ /* DCE6.0 and DCE8.0 has a HW issue when accessing registers
-+ * from ROM block. When there is a W access following R or W access
-+ * right after (no more than couple of cycles) the first W access
-+ * sometimes is not executed (in rate of about once per 100K tries).
-+ * It creates problems in different scenarios of FL setup. */
-+ cap->bugs.ROM_REGISTER_ACCESS = true;
-+
-+ /* VCE is supported */
-+ cap->caps.VCE_SUPPORTED = true;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/asic_capability/hawaii_asic_capability.h b/drivers/gpu/drm/amd/dal/dc/asic_capability/hawaii_asic_capability.h
-new file mode 100644
-index 0000000..191d9b2
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/asic_capability/hawaii_asic_capability.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_BONAIRE_CAPABILITY_H__
-+#define __DAL_BONAIRE_CAPABILITY_H__
-+
-+/* Forward declaration */
-+struct asic_capability;
-+struct hw_asic_id;
-+
-+/* Create and initialise Bonaire data */
-+void dal_hawaii_asic_capability_create(struct asic_capability *cap,
-+ struct hw_asic_id *init);
-+
-+#endif /* __DAL_BONAIRE_CAPABILITY_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/Makefile b/drivers/gpu/drm/amd/dal/dc/audio/Makefile
-index 0999372..2433d90 100644
---- a/drivers/gpu/drm/amd/dal/dc/audio/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/Makefile
-@@ -11,6 +11,18 @@ AMD_DAL_FILES += $(AMD_DAL_AUDIO)
-
-
- ###############################################################################
-+# DCE 8x
-+###############################################################################
-+ifdef CONFIG_DRM_AMD_DAL_DCE8_0
-+AUDIO_DCE80 = audio_dce80.o hw_ctx_audio_dce80.o
-+
-+AMD_DAL_AUDIO_DCE80 = $(addprefix $(AMDDALPATH)/dc/audio/dce80/,$(AUDIO_DCE80))
-+
-+AMD_DAL_FILES += $(AMD_DAL_AUDIO_DCE80)
-+endif
-+
-+
-+###############################################################################
- # DCE 11x
- ###############################################################################
- ifdef CONFIG_DRM_AMD_DAL_DCE11_0
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/audio_base.c b/drivers/gpu/drm/amd/dal/dc/audio/audio_base.c
-index bfd6725..269c75d 100644
---- a/drivers/gpu/drm/amd/dal/dc/audio/audio_base.c
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/audio_base.c
-@@ -30,6 +30,11 @@
- #include "audio.h"
- #include "hw_ctx_audio.h"
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+#include "dce80/audio_dce80.h"
-+#include "dce80/hw_ctx_audio_dce80.h"
-+#endif
-+
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
- #include "dce110/audio_dce110.h"
- #include "dce110/hw_ctx_audio_dce110.h"
-@@ -264,6 +269,10 @@ struct audio *dal_audio_create(
-
- as = init_data->as;
- switch (dal_adapter_service_get_dce_version(as)) {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ case DCE_VERSION_8_0:
-+ return dal_audio_create_dce80(init_data);
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- case DCE_VERSION_10_0:
- return dal_audio_create_dce110(init_data);
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/dce80/audio_dce80.c b/drivers/gpu/drm/amd/dal/dc/audio/dce80/audio_dce80.c
-new file mode 100644
-index 0000000..d6f437c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/dce80/audio_dce80.c
-@@ -0,0 +1,434 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+#include "include/logger_interface.h"
-+
-+#include "audio_dce80.h"
-+
-+/***** static functions *****/
-+
-+static void destruct(struct audio_dce80 *audio)
-+{
-+ /*release memory allocated for hw_ctx -- allocated is initiated
-+ *by audio_dce80 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_dce80 *audio = NULL;
-+
-+ audio = container_of(*ptr, struct audio_dce80, base);
-+
-+ destruct(audio);
-+
-+ /* release memory allocated for audio_dce80*/
-+ dm_free(audio->base.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_dce80.
-+ */
-+
-+/**
-+* Setup
-+*
-+* @brief
-+* setup Audio HW block, to be called by dal_audio_setup
-+*
-+* @param
-+* engine_id - HDMI engine id
-+* pTiming - CRTC timing
-+* actualPixelClock - actual programmed pixel clock
-+*/
-+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:
-+ case SIGNAL_TYPE_WIRELESS:
-+ /* setup HDMI audio engine */
-+ audio->hw_ctx->funcs->setup_hdmi_audio(
-+ audio->hw_ctx, output->engine_id, &output->crtc_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 */
-+ break;
-+ default:
-+ return AUDIO_RESULT_ERROR;
-+ }
-+
-+ /* setup Azalia block */
-+ audio->hw_ctx->funcs->setup_azalia(
-+ audio->hw_ctx,
-+ output->engine_id,
-+ output->signal,
-+ &output->crtc_info,
-+ &output->pll_info,
-+ info);
-+
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/**
-+* enable_output
-+*
-+* @brief
-+* enable Audio HW block, to be called by dal_audio_enable_output
-+*
-+* @param
-+* engine_id - HDMI engine id
-+*/
-+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: {
-+ /* 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
-+*
-+* @param
-+* engine_id - HDMI engine id
-+*/
-+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);
-+ 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);
-+ }
-+ break;
-+ default:
-+ return AUDIO_RESULT_ERROR;
-+ }
-+
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/**
-+* unmute
-+*
-+* @brief
-+* unmute audio, to be called by dal_audio_unmute
-+*
-+* @param
-+* engine_id - engine id
-+*/
-+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_WIRELESS:
-+ 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;
-+ default:
-+ return AUDIO_RESULT_ERROR;
-+ }
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/**
-+* mute
-+*
-+* @brief
-+* mute audio, to be called by dal_audio_nmute
-+*
-+* @param
-+* engine_id - engine id
-+*/
-+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_WIRELESS:
-+ 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;
-+ 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.
-+*
-+* @param
-+* NONE
-+*/
-+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_audio_create_hw_ctx_audio_dce80(
-+ 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);
-+
-+ if (dal_adapter_service_is_feature_supported(FEATURE_LIGHT_SLEEP))
-+ audio->hw_ctx->funcs->disable_az_clock_gating(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;
-+ }
-+}
-+
-+/**
-+* SetUnsolicitedResponsePayload
-+*
-+* @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);
-+}
-+
-+/**
-+* SetupAudioDTO
-+*
-+* @brief
-+* Update audio source clock from hardware context.
-+*
-+* @param
-+* determines if we have a HDMI link active
-+* known pixel rate for HDMI
-+* known DCPLL frequency
-+*/
-+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);
-+}
-+
-+/**
-+* GetSupportedFeatures
-+*
-+* @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
-+*
-+* @param
-+* NONE
-+*/
-+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.ENGINE_DIGD = 1;
-+ afs.ENGINE_DIGE = 1;
-+ afs.ENGINE_DIGF = 1;
-+ afs.ENGINE_DIGG = 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_dce80 *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_dce80(
-+ const struct audio_init_data *init_data)
-+{
-+ /*allocate memory for audio_dce80 */
-+ struct audio_dce80 *audio = dm_alloc(init_data->ctx, sizeof(struct audio_dce80));
-+
-+ if (audio == NULL)
-+ return NULL;
-+
-+ /*pointer to base_audio_block of audio_dce80 ==> audio base object */
-+ if (construct(audio, init_data))
-+ return &audio->base;
-+
-+ /*release memory allocated if fail */
-+ dm_free(init_data->ctx, audio);
-+ return NULL;
-+}
-+
-+/* Do not need expose construct_dce80 and destruct_dce80 becuase there is
-+ *derived object after dce80
-+ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/dce80/audio_dce80.h b/drivers/gpu/drm/amd/dal/dc/audio/dce80/audio_dce80.h
-new file mode 100644
-index 0000000..4fef455
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/dce80/audio_dce80.h
-@@ -0,0 +1,41 @@
-+/*
-+ * 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_80__
-+#define __DAL_AUDIO_80__
-+
-+#include "audio/audio.h"
-+#include "audio/hw_ctx_audio.h"
-+#include "audio/dce80/hw_ctx_audio_dce80.h"
-+
-+
-+struct audio_dce80 {
-+ struct audio base;
-+ /* dce-specific members are following */
-+ /* none */
-+};
-+
-+struct audio *dal_audio_create_dce80(const struct audio_init_data *init_data);
-+
-+#endif /* __DAL_AUDIO_80__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/dce80/hw_ctx_audio_dce80.c b/drivers/gpu/drm/amd/dal/dc/audio/dce80/hw_ctx_audio_dce80.c
-new file mode 100644
-index 0000000..521ad07
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/dce80/hw_ctx_audio_dce80.c
-@@ -0,0 +1,1926 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+#include "include/logger_interface.h"
-+#include "../hw_ctx_audio.h"
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+#include "hw_ctx_audio_dce80.h"
-+
-+#define FROM_BASE(ptr) \
-+ container_of((ptr), struct hw_ctx_audio_dce80, 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
-+
-+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,
-+ mmDIG4_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+ mmDIG5_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+ mmDIG6_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL
-+};
-+/* --- static functions --- */
-+
-+/* static void dal_audio_destruct_hw_ctx_audio_dce80(
-+ struct hw_ctx_audio_dce80 *ctx);*/
-+
-+
-+static void destroy(
-+ struct hw_ctx_audio **ptr)
-+{
-+ struct hw_ctx_audio_dce80 *hw_ctx_dce80;
-+
-+ hw_ctx_dce80 = container_of(
-+ *ptr, struct hw_ctx_audio_dce80, base);
-+
-+ dal_audio_destruct_hw_ctx_audio_dce80(hw_ctx_dce80);
-+ /* release memory allocated for struct hw_ctx_audio_dce80 */
-+ dm_free((*ptr)->ctx, hw_ctx_dce80);
-+
-+ *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);
-+
-+ dm_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);
-+ dm_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);
-+
-+ dm_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 = dm_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)
-+{
-+ if (hbr_channel_count > 7)
-+ return;
-+
-+ {
-+ union AZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL value;
-+
-+ value.u32All = dal_read_reg(
-+ mmAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL);
-+ value.bits.HBR_CHANNEL_COUNT = hbr_channel_count;
-+ dal_write_reg(
-+ mmAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL, value.u32All);
-+ }
-+}*/
-+
-+/* set compressed audio channel cound */
-+/*static void set_compressed_audio_channel_count(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t compressed_audio_ch_count)
-+{
-+ if (compressed_audio_ch_count > 7)
-+ return;
-+
-+ {
-+ union AZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL value;
-+
-+ value.u32All = dal_read_reg(
-+ mmAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL);
-+ value.bits.COMPRESSED_CHANNEL_COUNT =
-+ compressed_audio_ch_count;
-+ dal_write_reg(
-+ mmAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL,
-+ value.u32All);
-+ }
-+}*/
-+
-+/* 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.u32All = dal_read_reg(mmAZALIA_CYCLIC_BUFFER_SYNC);
-+ value.bits.CYCLIC_BUFFER_SYNC_ENABLE = 1;
-+ dal_write_reg(mmAZALIA_CYCLIC_BUFFER_SYNC, value.u32All);
-+}*/
-+
-+
-+
-+/* disable HW/SW Sync */
-+/*static void disable_hw_sw_sync(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ union AZALIA_CYCLIC_BUFFER_SYNC value;
-+
-+ value.u32All = dal_read_reg(
-+ mmAZALIA_CYCLIC_BUFFER_SYNC);
-+ value.bits.CYCLIC_BUFFER_SYNC_ENABLE = 0;
-+ dal_write_reg(
-+ mmAZALIA_CYCLIC_BUFFER_SYNC, value.u32All);
-+}*/
-+
-+
-+/* 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.u32All = 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.u32All);
-+}*/
-+
-+
-+/* 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 = dm_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);
-+
-+ dm_write_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO_SOURCE, value);
-+ }
-+
-+ /* module */
-+ {
-+ value = dm_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);
-+ dm_write_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO0_MODULE, value);
-+ }
-+
-+ /* phase */
-+ {
-+ value = 0;
-+
-+ value = dm_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);
-+
-+ dm_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);
-+
-+ dm_write_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO_SOURCE, value);
-+ }
-+
-+ /* module */
-+ {
-+ value = 0;
-+
-+ value = dm_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);
-+
-+ dm_write_reg(hw_ctx->ctx,
-+ mmDCCG_AUDIO_DTO1_MODULE, value);
-+ }
-+
-+ /* phase */
-+ {
-+ value = 0;
-+
-+ value = dm_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);
-+
-+ dm_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 = dm_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);
-+
-+ dm_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* AFMT_AUDIO_PACKET_CONTROL */
-+ {
-+ addr = mmAFMT_AUDIO_PACKET_CONTROL + engine_offset[engine_id];
-+
-+ value = dm_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, 1,
-+ AFMT_AUDIO_PACKET_CONTROL,
-+ AFMT_60958_CS_UPDATE);
-+
-+ dm_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* AFMT_AUDIO_PACKET_CONTROL2 */
-+ {
-+ addr = mmAFMT_AUDIO_PACKET_CONTROL2 + engine_offset[engine_id];
-+
-+ value = dm_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);
-+
-+ dm_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* HDMI_ACR_PACKET_CONTROL */
-+ {
-+ addr = mmHDMI_ACR_PACKET_CONTROL + engine_offset[engine_id];
-+
-+ value = dm_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);
-+
-+ dm_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 = dm_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, audio_clock_info.cts_32khz,
-+ HDMI_ACR_32_0,
-+ HDMI_ACR_CTS_32);
-+
-+ dm_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 = dm_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, audio_clock_info.n_32khz,
-+ HDMI_ACR_32_1,
-+ HDMI_ACR_N_32);
-+
-+ dm_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 = dm_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, audio_clock_info.cts_44khz,
-+ HDMI_ACR_44_0,
-+ HDMI_ACR_CTS_44);
-+
-+ dm_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 = dm_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, audio_clock_info.n_44khz,
-+ HDMI_ACR_44_1,
-+ HDMI_ACR_N_44);
-+
-+ dm_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 = dm_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, audio_clock_info.cts_48khz,
-+ HDMI_ACR_48_0,
-+ HDMI_ACR_CTS_48);
-+
-+ dm_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 = dm_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, audio_clock_info.n_48khz,
-+ HDMI_ACR_48_1,
-+ HDMI_ACR_N_48);
-+
-+ dm_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 = dm_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);
-+
-+ dm_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 = dm_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, 2,
-+ AFMT_60958_1,
-+ AFMT_60958_CS_CHANNEL_NUMBER_R);
-+
-+ dm_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 = dm_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);
-+
-+ dm_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);
-+ dm_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);
-+
-+ dm_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 = dm_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value,
-+ 1,
-+ AFMT_AUDIO_PACKET_CONTROL,
-+ AFMT_60958_CS_UPDATE);
-+
-+ dm_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* AFMT_AUDIO_PACKET_CONTROL2 */
-+ {
-+ addr =
-+ mmAFMT_AUDIO_PACKET_CONTROL2 + engine_offset[engine_id];
-+
-+ value = 0;
-+
-+ value = dm_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);
-+
-+ dm_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* AFMT_INFOFRAME_CONTROL0 */
-+ {
-+ addr =
-+ mmAFMT_INFOFRAME_CONTROL0 + engine_offset[engine_id];
-+
-+ value = 0;
-+
-+ value = dm_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value,
-+ 1,
-+ AFMT_INFOFRAME_CONTROL0,
-+ AFMT_AUDIO_INFO_UPDATE);
-+
-+ dm_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 = dm_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value,
-+ 0,
-+ AFMT_60958_0,
-+ AFMT_60958_CS_CLOCK_ACCURACY);
-+
-+ dm_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+}
-+
-+ /* setup VCE audio */
-+static void setup_vce_audio(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ /*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);*/
-+}
-+
-+/* 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 = dm_read_reg(hw_ctx->ctx, addr);
-+ set_reg_field_value(value, 1,
-+ DP_SEC_CNTL,
-+ DP_SEC_ASP_ENABLE);
-+
-+ dm_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);
-+
-+ dm_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);
-+
-+ dm_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 = dm_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);
-+
-+ dm_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);
-+
-+ 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);
-+
-+ /* 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)
-+ dm_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);
-+
-+ dm_write_reg(hw_ctx->ctx, addr, value);
-+ }
-+
-+ /* Channel allocation */
-+ {
-+ const uint32_t addr =
-+ mmAFMT_AUDIO_PACKET_CONTROL2 + engine_offset[engine_id];
-+ uint32_t value = dm_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value,
-+ channels,
-+ AFMT_AUDIO_PACKET_CONTROL2,
-+ AFMT_AUDIO_CHANNEL_ENABLE);
-+
-+ dm_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 = dm_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, 1,
-+ AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND);
-+
-+ dm_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 = dm_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, 0,
-+ AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND);
-+
-+ dm_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 = dm_read_reg(hw_ctx->ctx, addr);
-+
-+ set_reg_field_value(value, 0x70,
-+ AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES,
-+ AUDIO_RATE_CAPABILITIES);
-+
-+ dm_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 = dm_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);
-+ dm_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);
-+}
-+
-+ /* Disable Azalia Clock Gating Feature */
-+static void disable_az_clock_gating(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ uint32_t value;
-+
-+ value = dm_read_reg(hw_ctx->ctx,
-+ mmAZALIA_CONTROLLER_CLOCK_GATING);
-+ set_reg_field_value(value, 0, AZALIA_CONTROLLER_CLOCK_GATING, ENABLE_CLOCK_GATING);
-+ dm_write_reg(hw_ctx->ctx,
-+ mmAZALIA_CONTROLLER_CLOCK_GATING, 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 =
-+ 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,
-+};
-+
-+bool dal_audio_construct_hw_ctx_audio_dce80(
-+ struct hw_ctx_audio_dce80 *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 dce80 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;
-+ case 5: {
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_index =
-+ mmAZF0ENDPOINT4_AZALIA_F0_CODEC_ENDPOINT_INDEX;
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_data =
-+ mmAZF0ENDPOINT4_AZALIA_F0_CODEC_ENDPOINT_DATA;
-+ }
-+ break;
-+ case 6: {
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_index =
-+ mmAZF0ENDPOINT5_AZALIA_F0_CODEC_ENDPOINT_INDEX;
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_data =
-+ mmAZF0ENDPOINT5_AZALIA_F0_CODEC_ENDPOINT_DATA;
-+ }
-+ break;
-+ case 7: {
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_index =
-+ mmAZF0ENDPOINT6_AZALIA_F0_CODEC_ENDPOINT_INDEX;
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_data =
-+ mmAZF0ENDPOINT6_AZALIA_F0_CODEC_ENDPOINT_DATA;
-+ }
-+ break;
-+ default:
-+ /*DALASSERT_MSG(false,("Invalid Azalia stream ID!"));*/
-+ BREAK_TO_DEBUGGER();
-+ break;
-+ }
-+
-+ return true;
-+}
-+
-+
-+/* audio_dce80 is derived from audio directly, not via dce80 */
-+
-+void dal_audio_destruct_hw_ctx_audio_dce80(
-+ struct hw_ctx_audio_dce80 *hw_ctx_dce80)
-+{
-+ dal_audio_destruct_hw_ctx_audio(&hw_ctx_dce80->base);
-+}
-+
-+struct hw_ctx_audio *dal_audio_create_hw_ctx_audio_dce80(
-+ struct dc_context *ctx,
-+ uint32_t azalia_stream_id)
-+{
-+ /* allocate memory for struc hw_ctx_audio_dce80 */
-+ struct hw_ctx_audio_dce80 *hw_ctx_dce80 =
-+ dm_alloc(ctx, sizeof(struct hw_ctx_audio_dce80));
-+
-+ if (!hw_ctx_dce80) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ /*return pointer to hw_ctx_audio back to caller -- audio object */
-+ if (dal_audio_construct_hw_ctx_audio_dce80(
-+ hw_ctx_dce80, azalia_stream_id, ctx))
-+ return &hw_ctx_dce80->base;
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ dm_free(ctx, hw_ctx_dce80);
-+
-+ return NULL;
-+}
-+
-+
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/dce80/hw_ctx_audio_dce80.h b/drivers/gpu/drm/amd/dal/dc/audio/dce80/hw_ctx_audio_dce80.h
-new file mode 100644
-index 0000000..1d0e00d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/dce80/hw_ctx_audio_dce80.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
-+ *
-+ */
-+
-+#ifndef __DAL_HW_CTX_AUDIO_DCE80_H__
-+#define __DAL_HW_CTX_AUDIO_DCE80_H__
-+
-+#include "audio/hw_ctx_audio.h"
-+
-+struct hw_ctx_audio_dce80 {
-+ 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 */
-+};
-+
-+
-+/* --- helpers --- all static functions*/
-+/*set_high_bit_rate_capable
-+set_hbr_channel_count
-+set_compressed_audio_channel_count
-+set_video_latency
-+set_audio_latency
-+enable_hw_sw_sync
-+disable_hw_sw_sync
-+update_sw_write_ptr
-+update_av_association
-+write_indirect_azalia_reg
-+read_indirect_azalia_reg
-+*/
-+
-+/* in case dce83 may derived from dce80, expose dce80 constructor
-+*and destroy for derived */
-+bool dal_audio_construct_hw_ctx_audio_dce80(
-+ struct hw_ctx_audio_dce80 *hw_ctx,
-+ uint8_t azalia_stream_id,
-+ struct dc_context *ctx);
-+
-+void dal_audio_destruct_hw_ctx_audio_dce80(
-+ struct hw_ctx_audio_dce80 *hw_ctx);
-+
-+struct hw_ctx_audio *dal_audio_create_hw_ctx_audio_dce80(
-+ struct dc_context *ctx,
-+ uint32_t azalia_stream_id);
-+
-+#endif /* __DAL_HW_CTX_AUDIO_DCE80_H__ */
-+
-+
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/Makefile b/drivers/gpu/drm/amd/dal/dc/bios/Makefile
-index ddfe457..e5c8876 100644
---- a/drivers/gpu/drm/amd/dal/dc/bios/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/Makefile
-@@ -12,6 +12,19 @@ ifndef CONFIG_DRM_AMD_DAL_VBIOS_PRESENT
- AMD_DAL_FILES := $(filter-out $(AMDDALPATH)/dc/bios/bios_parser_helper.o,$(AMD_DAL_FILES))
- endif
-
-+###############################################################################
-+# DCE 8x
-+###############################################################################
-+# All DCE8.x are derived from DCE8.0, so 8.0 MUST be defined if ANY of
-+# DCE8.x is compiled.
-+ifdef CONFIG_DRM_AMD_DAL_DCE8_0
-+
-+ifdef CONFIG_DRM_AMD_DAL_VBIOS_PRESENT
-+AMD_DAL_FILES += $(AMDDALPATH)/dc/bios/dce80/bios_parser_helper_dce80.o
-+endif
-+
-+AMD_DAL_FILES += $(AMDDALPATH)/dc/bios/dce80/command_table_helper_dce80.o
-+endif
-
- ###############################################################################
- # DCE 11x
-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
-index 0aa227a..4e2bc90 100644
---- a/drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.c
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.c
-@@ -38,7 +38,11 @@ bool dal_bios_parser_init_bios_helper(
- enum dce_version version)
- {
- switch (version) {
--
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ case DCE_VERSION_8_0:
-+ bp->bios_helper = dal_bios_parser_helper_dce80_get_table();
-+ return true;
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- case DCE_VERSION_10_0:
- bp->bios_helper = dal_bios_parser_helper_dce110_get_table();
-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
-index 1ad7455..c58b9bb 100644
---- a/drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.h
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.h
-@@ -26,6 +26,10 @@
- #ifndef __DAL_BIOS_PARSER_HELPER_H__
- #define __DAL_BIOS_PARSER_HELPER_H__
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+#include "dce80/bios_parser_helper_dce80.h"
-+#endif
-+
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0) || defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- #include "dce110/bios_parser_helper_dce110.h"
- #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
-index 566604e..85a5924 100644
---- a/drivers/gpu/drm/amd/dal/dc/bios/command_table_helper.c
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/command_table_helper.c
-@@ -37,6 +37,11 @@ bool dal_bios_parser_init_cmd_tbl_helper(
- enum dce_version dce)
- {
- switch (dce) {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ case DCE_VERSION_8_0:
-+ *h = dal_cmd_tbl_helper_dce80_get_table();
-+ return true;
-+#endif
-
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- case DCE_VERSION_10_0:
-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
-index 4646cab..a462917 100644
---- a/drivers/gpu/drm/amd/dal/dc/bios/command_table_helper.h
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/command_table_helper.h
-@@ -26,6 +26,9 @@
- #ifndef __DAL_COMMAND_TABLE_HELPER_H__
- #define __DAL_COMMAND_TABLE_HELPER_H__
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+#include "dce80/command_table_helper_dce80.h"
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0) || defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- #include "dce110/command_table_helper_dce110.h"
- #endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/dce80/bios_parser_helper_dce80.c b/drivers/gpu/drm/amd/dal/dc/bios/dce80/bios_parser_helper_dce80.c
-new file mode 100644
-index 0000000..541a8c4
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/dce80/bios_parser_helper_dce80.c
-@@ -0,0 +1,773 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+#include "atom.h"
-+
-+#include "dce/dce_8_0_d.h"
-+#include "bif/bif_4_1_d.h"
-+
-+#include "include/grph_object_id.h"
-+#include "include/grph_object_defs.h"
-+#include "include/grph_object_ctrl_defs.h"
-+#include "include/bios_parser_types.h"
-+#include "include/adapter_service_types.h"
-+
-+#include "../bios_parser_helper.h"
-+
-+
-+static const uint8_t bios_scratch0_dacb_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)
-+{
-+ enum signal_type sink = SIGNAL_TYPE_NONE;
-+ /* VBIOS does not provide bitfield definitions */
-+ uint32_t reg;
-+ /* DCE 8.0 does not support DAC2 */
-+ if (encoder.id == ENCODER_ID_INTERNAL_DAC2
-+ || encoder.id == ENCODER_ID_INTERNAL_KLDSCP_DAC2) {
-+ BREAK_TO_DEBUGGER();
-+ /* TODO: DALASSERT_MSG(false, ("%s: DCE 8.0 Does not support
-+ * DAC2!", __FUNCTION__)); */
-+ return SIGNAL_TYPE_NONE;
-+ }
-+
-+ reg = dm_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) {
-+ reg <<= bios_scratch0_dacb_shift;
-+ }
-+
-+ switch (signal) {
-+ case SIGNAL_TYPE_RGB:
-+ if (reg & ATOM_S0_CRT2_MASK)
-+ sink = SIGNAL_TYPE_RGB;
-+ break;
-+ case SIGNAL_TYPE_LVDS:
-+ if (reg & ATOM_S0_LCD1)
-+ sink = SIGNAL_TYPE_LVDS;
-+ break;
-+ case SIGNAL_TYPE_EDP:
-+ if (reg & ATOM_S0_LCD1)
-+ sink = SIGNAL_TYPE_EDP;
-+ break;
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ break;
-+ }
-+
-+ return sink;
-+}
-+
-+static bool is_lid_open(struct dc_context *ctx)
-+{
-+ bool result = false;
-+
-+ /* VBIOS does not provide bitfield definitions */
-+ uint32_t reg;
-+
-+ reg = dm_read_reg(ctx,
-+ mmBIOS_SCRATCH_0 + ATOM_ACC_CHANGE_INFO_DEF);
-+
-+ /* lid is open if the bit is not set */
-+ result = !(reg & ATOM_S6_LID_STATE);
-+
-+ return result;
-+}
-+
-+static bool is_lid_status_changed(
-+ struct dc_context *ctx)
-+{
-+ bool result = false;
-+
-+ /* VBIOS does not provide bitfield definitions */
-+ uint32_t reg;
-+
-+ reg = dm_read_reg(ctx,
-+ mmBIOS_SCRATCH_6);
-+
-+ /* lid is open if the bit is not set */
-+ if (reg & ATOM_S6_LID_CHANGE) {
-+ reg &= ~ATOM_S6_LID_CHANGE;
-+ dm_write_reg(ctx,
-+ mmBIOS_SCRATCH_6, reg);
-+
-+ result = true;
-+ }
-+
-+ return result;
-+}
-+
-+static bool is_display_config_changed(
-+ struct dc_context *ctx)
-+{
-+ bool result = false;
-+
-+ /* VBIOS does not provide bitfield definitions */
-+ uint32_t reg;
-+
-+ reg = dm_read_reg(ctx,
-+ mmBIOS_SCRATCH_6);
-+
-+ /* lid is open if the bit is not set */
-+ if (reg & ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK) {
-+ reg &= ~ATOM_S6_CONFIG_DISPLAY_CHANGE_MASK;
-+ dm_write_reg(ctx,
-+ mmBIOS_SCRATCH_6, reg);
-+
-+ result = true;
-+ }
-+
-+ return result;
-+}
-+
-+/**
-+ * 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
-+ * NONE
-+ */
-+static void set_scratch_acc_mode_change(
-+ struct dc_context *ctx)
-+{
-+ uint32_t addr = mmBIOS_SCRATCH_6;
-+ uint32_t value = 0;
-+
-+ value = dm_read_reg(ctx, addr);
-+
-+ value |= ATOM_S6_ACC_MODE;
-+
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+/**
-+ * is_accelerated_mode
-+ *
-+ * @brief
-+ * set Accelerated Mode in VBIOS scratch register, VBIOS will clean it when
-+ * VGA/non-Accelerated mode is set
-+ *
-+ * @param
-+ * NONE
-+ */
-+static bool is_accelerated_mode(
-+ struct dc_context *ctx)
-+{
-+ uint32_t addr = mmBIOS_SCRATCH_6;
-+ uint32_t value = dm_read_reg(ctx, addr);
-+
-+ return (value & ATOM_S6_ACC_MODE) ? true : false;
-+}
-+
-+static void set_scratch_critical_state(
-+ struct dc_context *ctx,
-+ bool state)
-+{
-+ uint32_t addr = mmBIOS_SCRATCH_6;
-+ uint32_t value = dm_read_reg(ctx, addr);
-+
-+ if (state)
-+ value |= ATOM_S6_CRITICAL_STATE;
-+ else
-+ value &= ~ATOM_S6_CRITICAL_STATE;
-+
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+/**
-+ * 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:
-+ /* TODO: DALASSERT_MSG(false, ("%s: DCE 8.0 Does
-+ * not support DAC2!", __FUNCTION__));
-+ */
-+ default:
-+ break;
-+ }
-+ break;
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ break;
-+ }
-+}
-+
-+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 = dm_read_reg(ctx, addr);
-+
-+ value &= ~ATOM_S3_DEVICE_ACTIVE_MASK;
-+ value |= (d->active & ATOM_S3_DEVICE_ACTIVE_MASK);
-+
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* mmBIOS_SCRATCH_6 = mmBIOS_SCRATCH_0 + ATOM_ACC_CHANGE_INFO_DEF */
-+ addr = mmBIOS_SCRATCH_6;
-+
-+ value = dm_read_reg(ctx, addr);
-+
-+ value &= ~ATOM_S6_ACC_REQ_MASK;
-+ value |= (d->requested & ATOM_S6_ACC_REQ_MASK);
-+
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* mmBIOS_SCRATCH_5 = mmBIOS_SCRATCH_0 + ATOM_DOS_REQ_INFO_DEF */
-+ addr = mmBIOS_SCRATCH_5;
-+
-+ value = dm_read_reg(ctx, addr);
-+
-+ value &= ~ATOM_S5_DOS_REQ_DEVICEw0;
-+ value |= (d->active & ATOM_S5_DOS_REQ_DEVICEw0);
-+
-+ dm_write_reg(ctx, addr, value);
-+
-+ d->active = 0;
-+ d->requested = 0;
-+}
-+
-+/**
-+ * 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:
-+ switch (device_tag->dev_id.enum_id) {
-+ case 1:
-+ update |= ATOM_S0_CRT1_COLOR;
-+ break;
-+ case 2:
-+ update |= ATOM_S0_CRT2_COLOR;
-+ break;
-+ default:
-+ break;
-+ }
-+ 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 = dm_read_reg(ctx, addr);
-+
-+ if (connected)
-+ value |= update;
-+ else
-+ value &= ~update;
-+
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+static void set_scratch_lcd_scale(
-+ struct dc_context *ctx,
-+ enum lcd_scale lcd_scale_request)
-+{
-+ uint32_t reg;
-+
-+ reg = dm_read_reg(ctx, mmBIOS_SCRATCH_6);
-+
-+ reg &= ~ATOM_S6_REQ_LCD_EXPANSION_FULL;
-+ reg &= ~ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIO;
-+
-+ switch (lcd_scale_request) {
-+ case LCD_SCALE_FULLPANEL:
-+ /* set Lcd Scale to Full Panel Mode */
-+ reg |= ATOM_S6_REQ_LCD_EXPANSION_FULL;
-+ break;
-+ case LCD_SCALE_ASPECTRATIO:
-+ /* set Lcd Scale to Aspect-Ratio Mode */
-+ reg |= ATOM_S6_REQ_LCD_EXPANSION_ASPEC_RATIO;
-+ break;
-+ case LCD_SCALE_NONE:
-+ default:
-+ break;
-+ }
-+
-+ dm_write_reg(ctx, mmBIOS_SCRATCH_6, reg);
-+}
-+
-+static enum lcd_scale get_scratch_lcd_scale(
-+ struct dc_context *ctx)
-+{
-+ uint32_t addr = mmBIOS_SCRATCH_6;
-+ uint32_t value = 0;
-+
-+ value = dm_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;
-+}
-+
-+static uint32_t fmt_control(
-+ struct dc_context *ctx,
-+ enum controller_id id,
-+ uint32_t *value)
-+{
-+ uint32_t result = 0;
-+ uint32_t reg;
-+
-+ switch (id) {
-+ case CONTROLLER_ID_D0:
-+ reg = mmFMT0_FMT_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D1:
-+ reg = mmFMT1_FMT_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D2:
-+ reg = mmFMT2_FMT_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D3:
-+ reg = mmFMT3_FMT_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D4:
-+ reg = mmFMT4_FMT_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D5:
-+ reg = mmFMT5_FMT_CONTROL;
-+ break;
-+ default:
-+ return result;
-+ }
-+
-+ if (value != NULL)
-+ dm_write_reg(ctx, reg, *value);
-+ else
-+ result = dm_read_reg(ctx, reg);
-+
-+ return result;
-+}
-+
-+static uint32_t fmt_bit_depth_control(
-+ struct dc_context *ctx,
-+ enum controller_id id,
-+ uint32_t *value)
-+{
-+ uint32_t addr;
-+
-+ switch (id) {
-+ case CONTROLLER_ID_D0:
-+ addr = mmFMT0_FMT_BIT_DEPTH_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D1:
-+ addr = mmFMT1_FMT_BIT_DEPTH_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D2:
-+ addr = mmFMT2_FMT_BIT_DEPTH_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D3:
-+ addr = mmFMT3_FMT_BIT_DEPTH_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D4:
-+ addr = mmFMT4_FMT_BIT_DEPTH_CONTROL;
-+ break;
-+ case CONTROLLER_ID_D5:
-+ addr = mmFMT5_FMT_BIT_DEPTH_CONTROL;
-+ break;
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ return 0;
-+ }
-+
-+ if (value != NULL) {
-+ dm_write_reg(ctx, addr, *value);
-+ return 0;
-+ } else {
-+ return dm_read_reg(ctx, addr);
-+ }
-+}
-+
-+/**
-+ * Read various BIOS Scratch registers and put the resulting information into a
-+ * PowerPlay internal structure (which is not dependent on register bit layout).
-+ */
-+static void get_bios_event_info(
-+ struct dc_context *ctx,
-+ struct bios_event_info *info)
-+{
-+ uint32_t s2, s6;
-+ uint32_t clear_mask;
-+
-+ dm_memset(info, 0, sizeof(struct bios_event_info));
-+
-+ /* Handle backlight event ONLY. PPLib still handling other events */
-+ s6 = dm_read_reg(ctx, mmBIOS_SCRATCH_6);
-+
-+ clear_mask = s6 & (ATOM_S6_VRI_BRIGHTNESS_CHANGE);
-+
-+ dm_write_reg(ctx,
-+ mmBIOS_SCRATCH_6, s6 & ~clear_mask);
-+
-+ s2 = dm_read_reg(ctx, mmBIOS_SCRATCH_2);
-+
-+ info->backlight_level = (s2 & ATOM_S2_CURRENT_BL_LEVEL_MASK)
-+ >> ATOM_S2_CURRENT_BL_LEVEL_SHIFT;
-+ info->backlight_changed = (0 != (s6 & ATOM_S6_VRI_BRIGHTNESS_CHANGE));
-+}
-+
-+static void take_backlight_control(
-+ struct dc_context *ctx,
-+ bool control)
-+{
-+ const uint32_t addr = mmBIOS_SCRATCH_2;
-+
-+ uint32_t s2;
-+
-+ s2 = dm_read_reg(ctx, addr);
-+
-+ if (control)
-+ s2 |= ATOM_S2_VRI_BRIGHT_ENABLE;
-+ else
-+ s2 &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
-+
-+ dm_write_reg(ctx, addr, s2);
-+}
-+
-+static uint32_t get_requested_backlight_level(
-+ struct dc_context *ctx)
-+{
-+ uint32_t s2;
-+
-+ s2 = dm_read_reg(ctx, mmBIOS_SCRATCH_2);
-+
-+ return (s2 & ATOM_S2_CURRENT_BL_LEVEL_MASK)
-+ >> ATOM_S2_CURRENT_BL_LEVEL_SHIFT;
-+}
-+
-+static void update_requested_backlight_level(
-+ struct dc_context *ctx,
-+ uint32_t backlight_8bit)
-+{
-+ const uint32_t addr = mmBIOS_SCRATCH_2;
-+
-+ uint32_t s2;
-+
-+ s2 = dm_read_reg(ctx, addr);
-+
-+ s2 &= ~ATOM_S2_CURRENT_BL_LEVEL_MASK;
-+ backlight_8bit &= (ATOM_S2_CURRENT_BL_LEVEL_MASK
-+ >> ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
-+ s2 |= (backlight_8bit << ATOM_S2_CURRENT_BL_LEVEL_SHIFT);
-+
-+ dm_write_reg(ctx, addr, s2);
-+}
-+
-+static bool is_active_display(
-+ struct dc_context *ctx,
-+ enum signal_type signal,
-+ const struct connector_device_tag_info *dev_tag)
-+{
-+ uint32_t active = 0;
-+
-+ uint32_t reg;
-+
-+ switch (signal) {
-+ 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:
-+ active = ATOM_S3_DFP1_ACTIVE;
-+ break;
-+ case 2:
-+ active = ATOM_S3_DFP2_ACTIVE;
-+ break;
-+ case 3:
-+ active = ATOM_S3_DFP3_ACTIVE;
-+ break;
-+ case 4:
-+ active = ATOM_S3_DFP4_ACTIVE;
-+ break;
-+ case 5:
-+ active = ATOM_S3_DFP5_ACTIVE;
-+ break;
-+
-+ case 6:
-+ active = ATOM_S3_DFP6_ACTIVE;
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ break;
-+ case SIGNAL_TYPE_LVDS:
-+ case SIGNAL_TYPE_EDP:
-+ active = ATOM_S3_LCD1_ACTIVE;
-+ break;
-+ case SIGNAL_TYPE_RGB:
-+ if (dev_tag->dev_id.device_type == DEVICE_TYPE_CRT)
-+ active = ATOM_S3_CRT1_ACTIVE;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ reg = dm_read_reg(ctx, mmBIOS_SCRATCH_3);
-+ reg &= ATOM_S3_DEVICE_ACTIVE_MASK;
-+
-+ return 0 != (active & reg);
-+}
-+
-+static enum controller_id get_embedded_display_controller_id(
-+ struct dc_context *ctx)
-+{
-+ uint32_t reg;
-+
-+ reg = dm_read_reg(ctx, mmBIOS_SCRATCH_3);
-+
-+ if (ATOM_S3_LCD1_ACTIVE & reg)
-+ return (reg & ATOM_S3_LCD1_CRTC_ACTIVE) ?
-+ CONTROLLER_ID_D1 : CONTROLLER_ID_D0;
-+
-+ return CONTROLLER_ID_UNDEFINED;
-+}
-+
-+static uint32_t get_embedded_display_refresh_rate(
-+ struct dc_context *ctx)
-+{
-+ uint32_t result = 0;
-+
-+ uint32_t reg_3;
-+
-+ reg_3 = dm_read_reg(ctx, mmBIOS_SCRATCH_3);
-+
-+ if (ATOM_S3_LCD1_ACTIVE & reg_3) {
-+ uint32_t reg_4;
-+
-+ reg_4 = dm_read_reg(ctx,
-+ mmBIOS_SCRATCH_4);
-+
-+ result = (reg_4 & ATOM_S4_LCD1_REFRESH_MASK)
-+ >> ATOM_S4_LCD1_REFRESH_SHIFT;
-+ }
-+
-+ return result;
-+}
-+
-+static const struct bios_parser_helper bios_parser_helper_funcs = {
-+ .detect_sink = detect_sink,
-+ .fmt_bit_depth_control = fmt_bit_depth_control,
-+ .fmt_control = fmt_control,
-+ .get_bios_event_info = get_bios_event_info,
-+ .get_embedded_display_controller_id =
-+ get_embedded_display_controller_id,
-+ .get_embedded_display_refresh_rate =
-+ get_embedded_display_refresh_rate,
-+ .get_requested_backlight_level = get_requested_backlight_level,
-+ .get_scratch_lcd_scale = get_scratch_lcd_scale,
-+ .is_accelerated_mode = is_accelerated_mode,
-+ .is_active_display = is_active_display,
-+ .is_display_config_changed = is_display_config_changed,
-+ .is_lid_open = is_lid_open,
-+ .is_lid_status_changed = is_lid_status_changed,
-+ .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 = take_backlight_control,
-+ .update_requested_backlight_level = update_requested_backlight_level,
-+};
-+
-+const struct bios_parser_helper *dal_bios_parser_helper_dce80_get_table()
-+{
-+ return &bios_parser_helper_funcs;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/dce80/bios_parser_helper_dce80.h b/drivers/gpu/drm/amd/dal/dc/bios/dce80/bios_parser_helper_dce80.h
-new file mode 100644
-index 0000000..db671be
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/dce80/bios_parser_helper_dce80.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_BIOS_PARSER_HELPER_DCE80_H__
-+#define __DAL_BIOS_PARSER_HELPER_DCE80_H__
-+
-+struct bios_parser_helper;
-+
-+const struct bios_parser_helper *dal_bios_parser_helper_dce80_get_table(void);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/dce80/command_table_helper_dce80.c b/drivers/gpu/drm/amd/dal/dc/bios/dce80/command_table_helper_dce80.c
-new file mode 100644
-index 0000000..d725c4c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/dce80/command_table_helper_dce80.c
-@@ -0,0 +1,355 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+#include "atom.h"
-+
-+#include "include/grph_object_id.h"
-+#include "include/grph_object_defs.h"
-+#include "include/bios_parser_types.h"
-+#include "include/adapter_service_types.h"
-+
-+#include "../command_table_helper.h"
-+
-+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 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_DACA:
-+ *atom_engine_id = ASIC_INT_DAC1_ENCODER_ID;
-+ result = true;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return result;
-+}
-+
-+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:
-+ BREAK_TO_DEBUGGER(); /* check when this will happen! */
-+ *atom_pll_id = ATOM_PPLL_INVALID;
-+ result = false;
-+ break;
-+ default:
-+ result = false;
-+ break;
-+ }
-+
-+ return result;
-+}
-+
-+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 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 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;
-+ default:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V5__DIGA_SEL;
-+ break;
-+ }
-+
-+ return atom_dig_encoder_sel;
-+}
-+
-+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 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:
-+ BREAK_TO_DEBUGGER(); /* Unhandle action in driver! */
-+ break;
-+ }
-+
-+ return atom_pipe_action;
-+}
-+
-+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 =
-+ dal_cmd_table_helper_assign_control_parameter,
-+ .clock_source_id_to_ref_clk_src =
-+ dal_cmd_table_helper_clock_source_id_to_ref_clk_src,
-+ .transmitter_bp_to_atom = dal_cmd_table_helper_transmitter_bp_to_atom,
-+ .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,
-+};
-+
-+const struct command_table_helper *dal_cmd_tbl_helper_dce80_get_table()
-+{
-+ return &command_table_helper_funcs;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/dce80/command_table_helper_dce80.h b/drivers/gpu/drm/amd/dal/dc/bios/dce80/command_table_helper_dce80.h
-new file mode 100644
-index 0000000..e675c35
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/dce80/command_table_helper_dce80.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_COMMAND_TABLE_HELPER_DCE80_H__
-+#define __DAL_COMMAND_TABLE_HELPER_DCE80_H__
-+
-+struct command_table_helper;
-+
-+const struct command_table_helper *dal_cmd_tbl_helper_dce80_get_table(void);
-+
-+#endif
-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
-index db4f131..133b174 100644
---- a/drivers/gpu/drm/amd/dal/dc/core/dc_hw_sequencer.c
-+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_hw_sequencer.c
-@@ -25,6 +25,9 @@
- #include "dm_services.h"
- #include "core_types.h"
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+#include "dce80/dce80_hw_sequencer.h"
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- #include "dce100/dce100_hw_sequencer.h"
- #endif
-@@ -40,6 +43,10 @@ bool dc_construct_hw_sequencer(
-
- switch (dce_ver)
- {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ case DCE_VERSION_8_0:
-+ return dce80_hw_sequencer_construct(dc);
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- case DCE_VERSION_10_0:
- return dce100_hw_sequencer_construct(dc);
-diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c b/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c
-index 70bf935..80fb823 100644
---- a/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c
-+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c
-@@ -31,6 +31,9 @@
- #include "opp.h"
- #include "transform.h"
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+#include "dce80/dce80_resource.h"
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- #include "dce100/dce100_resource.h"
- #endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/Makefile b/drivers/gpu/drm/amd/dal/dc/dce80/Makefile
-new file mode 100644
-index 0000000..efe001f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/Makefile
-@@ -0,0 +1,17 @@
-+#
-+# Makefile for the 'controller' sub-component of DAL.
-+# It provides the control and status of HW CRTC block.
-+
-+DCE80 = dce80_ipp.o dce80_ipp_gamma.o dce80_link_encoder.o dce80_opp.o \
-+ dce80_opp_formatter.o dce80_opp_regamma.o dce80_stream_encoder.o \
-+ dce80_timing_generator.o dce80_transform.o dce80_transform_gamut.o \
-+ dce80_transform_scl.o dce80_opp_csc.o\
-+ dce80_compressor.o dce80_mem_input.o dce80_hw_sequencer.o \
-+ dce80_transform_bit_depth.o dce80_resource.o
-+
-+AMD_DAL_DCE80 = $(addprefix $(AMDDALPATH)/dc/dce80/,$(DCE80))
-+
-+AMD_DAL_FILES += $(AMD_DAL_DCE80)
-+
-+
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_compressor.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_compressor.c
-new file mode 100644
-index 0000000..a3b767e
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_compressor.c
-@@ -0,0 +1,867 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+#include "gmc/gmc_7_1_sh_mask.h"
-+#include "gmc/gmc_7_1_d.h"
-+
-+#include "include/logger_interface.h"
-+#include "include/adapter_service_interface.h"
-+
-+#include "dce80_compressor.h"
-+
-+#define DCP_REG(reg)\
-+ (reg + cp80->offsets.dcp_offset)
-+#define DMIF_REG(reg)\
-+ (reg + cp80->offsets.dmif_offset)
-+
-+static const struct dce80_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),
-+},
-+{
-+ .dcp_offset = (mmDCP3_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif_offset = (mmDMIF_PG3_DPG_PIPE_DPM_CONTROL
-+ - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP4_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif_offset = (mmDMIF_PG4_DPG_PIPE_DPM_CONTROL
-+ - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP5_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif_offset = (mmDMIF_PG5_DPG_PIPE_DPM_CONTROL
-+ - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-+}
-+};
-+
-+static const uint32_t dce8_one_lpt_channel_max_resolution = 2048 * 1200;
-+
-+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 dce80_compressor *cp80)
-+{
-+ /*LPT_ALIGNMENT (in bytes) = ROW_SIZE * #BANKS * # DRAM CHANNELS. */
-+ return cp80->base.raw_size * cp80->base.banks_num *
-+ cp80->base.dram_channels_num;
-+}
-+
-+static uint32_t lpt_memory_control_config(struct dce80_compressor *cp80,
-+ uint32_t lpt_control)
-+{
-+ /*LPT MC Config */
-+ if (cp80->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 (cp80->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(
-+ cp80->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 (cp80->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(
-+ cp80->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 (cp80->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(
-+ cp80->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 (cp80->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(
-+ cp80->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: Invalid LPT ROW_SIZE!!!",
-+ __func__);
-+ break;
-+ }
-+ } else {
-+ dal_logger_write(
-+ cp80->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 dce80_compressor *cp80,
-+ uint32_t source_view_width,
-+ uint32_t source_view_height)
-+{
-+ if (cp80->base.embedded_panel_h_size != 0 &&
-+ cp80->base.embedded_panel_v_size != 0 &&
-+ ((source_view_width * source_view_height) >
-+ (cp80->base.embedded_panel_h_size *
-+ cp80->base.embedded_panel_v_size)))
-+ return true;
-+
-+ return false;
-+}
-+
-+static uint32_t align_to_chunks_number_per_line(
-+ struct dce80_compressor *cp80,
-+ uint32_t pixels)
-+{
-+ return 256 * ((pixels + 255) / 256);
-+}
-+
-+static void wait_for_fbc_state_changed(
-+ struct dce80_compressor *cp80,
-+ bool enabled)
-+{
-+ uint8_t counter = 0;
-+ uint32_t addr = mmFBC_STATUS;
-+ uint32_t value;
-+
-+ while (counter < 10) {
-+ value = dm_read_reg(cp80->base.ctx, addr);
-+ if (get_reg_field_value(
-+ value,
-+ FBC_STATUS,
-+ FBC_ENABLE_STATUS) == enabled)
-+ break;
-+ dm_delay_in_microseconds(cp80->base.ctx, 10);
-+ counter++;
-+ }
-+
-+ if (counter == 10) {
-+ dal_logger_write(
-+ cp80->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: wait counter exceeded, changes to HW not applied",
-+ __func__);
-+ }
-+}
-+
-+void dce80_compressor_power_up_fbc(struct compressor *compressor)
-+{
-+ uint32_t value;
-+ uint32_t addr;
-+
-+ addr = mmFBC_CNTL;
-+ value = dm_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);
-+ dm_write_reg(compressor->ctx, addr, value);
-+
-+ addr = mmFBC_COMP_MODE;
-+ value = dm_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);
-+ dm_write_reg(compressor->ctx, addr, value);
-+
-+ addr = mmFBC_COMP_CNTL;
-+ value = dm_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(value, 1, FBC_COMP_CNTL, FBC_DEPTH_RGB08_EN);
-+ dm_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);
-+ dm_write_reg(compressor->ctx, addr, value);
-+ compressor->min_compress_ratio = FBC_COMPRESS_RATIO_1TO1;
-+
-+ value = 0;
-+ dm_write_reg(compressor->ctx, mmFBC_IND_LUT0, value);
-+
-+ value = 0xFFFFFF;
-+ dm_write_reg(compressor->ctx, mmFBC_IND_LUT1, value);
-+}
-+
-+void dce80_compressor_enable_fbc(
-+ struct compressor *compressor,
-+ uint32_t paths_num,
-+ struct compr_addr_and_pitch_params *params)
-+{
-+ struct dce80_compressor *cp80 = TO_DCE80_COMPRESSOR(compressor);
-+
-+ if (compressor->options.bits.FBC_SUPPORT &&
-+ (compressor->options.bits.DUMMY_BACKEND == 0) &&
-+ (!dce80_compressor_is_fbc_enabled_in_hw(compressor, NULL)) &&
-+ (!is_source_bigger_than_epanel_size(
-+ cp80,
-+ 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 <=
-+ dce8_one_lpt_channel_max_resolution)) {
-+ dce80_compressor_enable_lpt(compressor);
-+ }
-+
-+ addr = mmFBC_CNTL;
-+ value = dm_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);
-+ dm_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;
-+ cp80->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);
-+ dm_write_reg(compressor->ctx, addr, value);
-+ set_reg_field_value(value, 1, FBC_CNTL, FBC_GRPH_COMP_EN);
-+ dm_write_reg(compressor->ctx, addr, value);
-+
-+ wait_for_fbc_state_changed(cp80, true);
-+ }
-+}
-+
-+void dce80_compressor_disable_fbc(struct compressor *compressor)
-+{
-+ struct dce80_compressor *cp80 = TO_DCE80_COMPRESSOR(compressor);
-+
-+ if (compressor->options.bits.FBC_SUPPORT &&
-+ dce80_compressor_is_fbc_enabled_in_hw(compressor, NULL)) {
-+ uint32_t reg_data;
-+ /* Turn off compression */
-+ reg_data = dm_read_reg(compressor->ctx, mmFBC_CNTL);
-+ set_reg_field_value(reg_data, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
-+ dm_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)
-+ dce80_compressor_disable_lpt(compressor);
-+
-+ wait_for_fbc_state_changed(cp80, false);
-+ }
-+}
-+
-+bool dce80_compressor_is_fbc_enabled_in_hw(
-+ struct compressor *compressor,
-+ uint32_t *inst)
-+{
-+ /* Check the hardware register */
-+ uint32_t value;
-+
-+ value = dm_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 = dm_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 dce80_compressor_is_lpt_enabled_in_hw(struct compressor *compressor)
-+{
-+ /* Check the hardware register */
-+ uint32_t value = dm_read_reg(compressor->ctx,
-+ mmLOW_POWER_TILING_CONTROL);
-+
-+ return get_reg_field_value(
-+ value,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ENABLE);
-+}
-+
-+void dce80_compressor_program_compressed_surface_address_and_pitch(
-+ struct compressor *compressor,
-+ struct compr_addr_and_pitch_params *params)
-+{
-+ struct dce80_compressor *cp80 = TO_DCE80_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. */
-+ dm_write_reg(
-+ compressor->ctx,
-+ DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS_HIGH),
-+ 0);
-+ dm_write_reg(compressor->ctx,
-+ DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS), 0);
-+
-+ if (compressor->options.bits.LPT_SUPPORT) {
-+ uint32_t lpt_alignment = lpt_size_alignment(cp80);
-+
-+ 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. */
-+ dm_write_reg(compressor->ctx,
-+ DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS_HIGH),
-+ compressor->compr_surface_address.addr.high_part);
-+ dm_write_reg(compressor->ctx,
-+ DCP_REG(mmGRPH_COMPRESS_SURFACE_ADDRESS),
-+ compressed_surf_address_low_part);
-+
-+ fbc_pitch = align_to_chunks_number_per_line(
-+ cp80,
-+ 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 DCE8 compression ratio",
-+ __func__);
-+
-+ /* Clear content first. */
-+ dm_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);
-+ dm_write_reg(compressor->ctx, DCP_REG(mmGRPH_COMPRESS_PITCH), value);
-+
-+}
-+
-+void dce80_compressor_disable_lpt(struct compressor *compressor)
-+{
-+ struct dce80_compressor *cp80 = TO_DCE80_COMPRESSOR(compressor);
-+ uint32_t value;
-+ uint32_t addr;
-+ uint32_t inx;
-+
-+ /* Disable all pipes LPT Stutter */
-+ for (inx = 0; inx < 3; inx++) {
-+ value =
-+ dm_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);
-+ dm_write_reg(
-+ compressor->ctx,
-+ DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH),
-+ value);
-+ }
-+
-+ /* Disable LPT */
-+ addr = mmLOW_POWER_TILING_CONTROL;
-+ value = dm_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ENABLE);
-+ dm_write_reg(compressor->ctx, addr, value);
-+
-+ /* Clear selection of Channel(s) containing Compressed Surface */
-+ addr = mmGMCON_LPT_TARGET;
-+ value = dm_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 0xFFFFFFFF,
-+ GMCON_LPT_TARGET,
-+ STCTRL_LPT_TARGET);
-+ dm_write_reg(compressor->ctx, mmGMCON_LPT_TARGET, value);
-+}
-+
-+void dce80_compressor_enable_lpt(struct compressor *compressor)
-+{
-+ struct dce80_compressor *cp80 = TO_DCE80_COMPRESSOR(compressor);
-+ uint32_t value;
-+ uint32_t addr;
-+ uint32_t value_control;
-+ uint32_t channels;
-+
-+ /* Enable LPT Stutter from Display pipe */
-+ value = dm_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);
-+ dm_write_reg(compressor->ctx,
-+ DMIF_REG(mmDPG_PIPE_STUTTER_CONTROL_NONLPTCH), 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 = dm_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 = dm_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);
-+ dm_write_reg(compressor->ctx, addr, value);
-+
-+ /* Enable LPT */
-+ addr = mmLOW_POWER_TILING_CONTROL;
-+ value = dm_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ENABLE);
-+ dm_write_reg(compressor->ctx, addr, value);
-+}
-+
-+void dce80_compressor_program_lpt_control(
-+ struct compressor *compressor,
-+ struct compr_addr_and_pitch_params *params)
-+{
-+ struct dce80_compressor *cp80 = TO_DCE80_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 = dm_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(cp80, 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(cp80);
-+ source_view_width =
-+ align_to_chunks_number_per_line(
-+ cp80,
-+ 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);
-+
-+ dm_write_reg(compressor->ctx,
-+ mmLOW_POWER_TILING_CONTROL, lpt_control);
-+}
-+
-+/*
-+ * DCE 11 Frame Buffer Compression Implementation
-+ */
-+
-+
-+void dce80_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 = dm_read_reg(compressor->ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ FBC_CLIENT_REGION_MASK,
-+ FBC_MEMORY_REGION_MASK);
-+ dm_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 DCE8:
-+ * - 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, DCE8.1 also needs to set new DCE8.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 = dm_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);
-+ dm_write_reg(compressor->ctx, addr, value);
-+}
-+
-+bool dce80_compressor_construct(struct dce80_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 *dce80_compressor_create(struct dc_context *ctx,
-+ struct adapter_service *as)
-+{
-+ struct dce80_compressor *cp80 =
-+ dm_alloc(ctx, sizeof(struct dce80_compressor));
-+
-+ if (!cp80)
-+ return NULL;
-+
-+ if (dce80_compressor_construct(cp80, ctx, as))
-+ return &cp80->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(ctx, cp80);
-+ return NULL;
-+}
-+
-+void dce80_compressor_destroy(struct compressor **compressor)
-+{
-+ dm_free((*compressor)->ctx, TO_DCE80_COMPRESSOR(*compressor));
-+ *compressor = NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_compressor.h b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_compressor.h
-new file mode 100644
-index 0000000..8254118
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_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_DCE80_H__
-+#define __DC_COMPRESSOR_DCE80_H__
-+
-+#include "../inc/compressor.h"
-+
-+#define TO_DCE80_COMPRESSOR(compressor)\
-+ container_of(compressor, struct dce80_compressor, base)
-+
-+struct dce80_compressor_reg_offsets {
-+ uint32_t dcp_offset;
-+ uint32_t dmif_offset;
-+};
-+
-+struct dce80_compressor {
-+ struct compressor base;
-+ struct dce80_compressor_reg_offsets offsets;
-+};
-+
-+struct compressor *dce80_compressor_create(struct dc_context *ctx,
-+ struct adapter_service *as);
-+
-+bool dce80_compressor_construct(struct dce80_compressor *cp80,
-+ struct dc_context *ctx, struct adapter_service *as);
-+
-+void dce80_compressor_destroy(struct compressor **cp);
-+
-+/* FBC RELATED */
-+void dce80_compressor_power_up_fbc(struct compressor *cp);
-+
-+void dce80_compressor_enable_fbc(struct compressor *cp, uint32_t paths_num,
-+ struct compr_addr_and_pitch_params *params);
-+
-+void dce80_compressor_disable_fbc(struct compressor *cp);
-+
-+void dce80_compressor_set_fbc_invalidation_triggers(struct compressor *cp,
-+ uint32_t fbc_trigger);
-+
-+void dce80_compressor_program_compressed_surface_address_and_pitch(
-+ struct compressor *cp,
-+ struct compr_addr_and_pitch_params *params);
-+
-+bool dce80_compressor_get_required_compressed_surface_size(
-+ struct compressor *cp,
-+ struct fbc_input_info *input_info,
-+ struct fbc_requested_compressed_size *size);
-+
-+bool dce80_compressor_is_fbc_enabled_in_hw(struct compressor *cp,
-+ uint32_t *fbc_mapped_crtc_id);
-+
-+/* LPT RELATED */
-+void dce80_compressor_enable_lpt(struct compressor *cp);
-+
-+void dce80_compressor_disable_lpt(struct compressor *cp);
-+
-+void dce80_compressor_program_lpt_control(struct compressor *cp,
-+ struct compr_addr_and_pitch_params *params);
-+
-+bool dce80_compressor_is_lpt_enabled_in_hw(struct compressor *cp);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.c
-new file mode 100644
-index 0000000..9f3201f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.c
-@@ -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
-+ *
-+ */
-+
-+#include "dm_services.h"
-+#include "dc.h"
-+#include "core_dc.h"
-+#include "core_types.h"
-+#include "dce80_hw_sequencer.h"
-+
-+#include "dce110/dce110_hw_sequencer.h"
-+
-+#include "gpu/dce80/dc_clock_gating_dce80.h"
-+
-+/* include DCE8 register header files */
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+struct dce80_hw_seq_reg_offsets {
-+ uint32_t blnd;
-+ uint32_t crtc;
-+};
-+
-+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
-+};
-+
-+static const struct dce80_hw_seq_reg_offsets reg_offsets[] = {
-+{
-+ .blnd = (mmBLND0_BLND_CONTROL - mmBLND_CONTROL),
-+ .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-+},
-+{
-+ .blnd = (mmBLND1_BLND_CONTROL - mmBLND_CONTROL),
-+ .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-+},
-+{
-+ .blnd = (mmBLND2_BLND_CONTROL - mmBLND_CONTROL),
-+ .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-+},
-+{
-+ .blnd = (mmBLND3_BLND_CONTROL - mmBLND_CONTROL),
-+ .crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-+},
-+{
-+ .blnd = (mmBLND4_BLND_CONTROL - mmBLND_CONTROL),
-+ .crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-+},
-+{
-+ .blnd = (mmBLND5_BLND_CONTROL - mmBLND_CONTROL),
-+ .crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL),
-+}
-+};
-+
-+#define HW_REG_BLND(reg, id)\
-+ (reg + reg_offsets[id].blnd)
-+
-+#define HW_REG_CRTC(reg, id)\
-+ (reg + reg_offsets[id].crtc)
-+
-+
-+
-+/*******************************************************************************
-+ * Private definitions
-+ ******************************************************************************/
-+
-+/***************************PIPE_CONTROL***********************************/
-+static void dce80_enable_fe_clock(
-+ struct dc_context *ctx, uint8_t controller_id, bool enable)
-+{
-+ uint32_t value = 0;
-+ uint32_t addr;
-+
-+ addr = HW_REG_CRTC(mmCRTC_DCFE_CLOCK_CONTROL, controller_id);
-+
-+ value = dm_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ enable,
-+ CRTC_DCFE_CLOCK_CONTROL,
-+ CRTC_DCFE_CLOCK_ENABLE);
-+
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+static bool dce80_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 = dm_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);
-+
-+ dm_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 = dm_read_reg(ctx, addr);
-+
-+ pipe_pending = 0;
-+
-+ 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++;
-+ dm_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. */
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+static void dce80_set_blender_mode(
-+ struct dc_context *ctx,
-+ uint8_t controller_id,
-+ uint32_t 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 = dm_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ blnd_mode,
-+ BLND_CONTROL,
-+ BLND_MODE);
-+
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+static bool dce80_enable_display_power_gating(
-+ struct dc_context *ctx,
-+ uint8_t controller_id,
-+ struct dc_bios *dcb,
-+ 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 != 0))
-+ bp_result = dcb->funcs->enable_disp_power_gating(
-+ dcb, controller_id + 1, cntl);
-+
-+ if (bp_result == BP_RESULT_OK)
-+ return true;
-+ else
-+ return false;
-+}
-+
-+bool dce80_hw_sequencer_construct(struct dc *dc)
-+{
-+ dce110_hw_sequencer_construct(dc);
-+
-+ dc->hwss.clock_gating_power_up = dal_dc_clock_gating_dce80_power_up;
-+ dc->hwss.enable_fe_clock = dce80_enable_fe_clock;
-+ dc->hwss.enable_display_power_gating = dce80_enable_display_power_gating;
-+ dc->hwss.pipe_control_lock = dce80_pipe_control_lock;
-+ dc->hwss.set_blender_mode = dce80_set_blender_mode;
-+
-+ return true;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.h b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_hw_sequencer.h
-new file mode 100644
-index 0000000..9d6dd05
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_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_DCE80_H__
-+#define __DC_HWSS_DCE80_H__
-+
-+#include "core_types.h"
-+
-+struct dc;
-+
-+bool dce80_hw_sequencer_construct(struct dc *dc);
-+
-+#endif /* __DC_HWSS_DCE80_H__ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp.c
-new file mode 100644
-index 0000000..6dde1eb
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp.c
-@@ -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
-+ *
-+ */
-+
-+#include "dm_services.h"
-+#include "include/logger_interface.h"
-+
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+#include "dce80_ipp.h"
-+
-+#include "dce110/dce110_ipp.h"
-+
-+static struct ipp_funcs funcs = {
-+ .ipp_cursor_set_attributes = dce110_ipp_cursor_set_attributes,
-+ .ipp_cursor_set_position = dce110_ipp_cursor_set_position,
-+ .ipp_program_prescale = dce110_ipp_program_prescale,
-+ .ipp_set_degamma = dce110_ipp_set_degamma,
-+};
-+
-+bool dce80_ipp_construct(
-+ struct dce110_ipp *ipp,
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_ipp_reg_offsets *offset)
-+{
-+ ipp->base.ctx = ctx;
-+
-+ ipp->base.inst = inst;
-+
-+ ipp->offsets = *offset;
-+
-+ ipp->base.funcs = &funcs;
-+
-+ return true;
-+}
-+
-+void dce80_ipp_destroy(struct input_pixel_processor **ipp)
-+{
-+ dm_free((*ipp)->ctx, TO_DCE80_IPP(*ipp));
-+ *ipp = NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp.h b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp.h
-new file mode 100644
-index 0000000..bd81693
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp.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 __DC_IPP_DCE80_H__
-+#define __DC_IPP_DCE80_H__
-+
-+#include "inc/ipp.h"
-+
-+#define TO_DCE80_IPP(input_pixel_processor)\
-+ container_of(input_pixel_processor, struct dce110_ipp, base)
-+
-+struct dce110_ipp;
-+struct dce110_ipp_reg_offsets;
-+struct gamma_parameters;
-+struct dev_c_lut;
-+
-+
-+bool dce80_ipp_construct(
-+ struct dce110_ipp *ipp,
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_ipp_reg_offsets *offset);
-+
-+void dce80_ipp_destroy(struct input_pixel_processor **ipp);
-+
-+
-+#endif /*__DC_IPP_DCE80_H__*/
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp_gamma.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp_gamma.c
-new file mode 100644
-index 0000000..fdffb8c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_ipp_gamma.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 "dm_services.h"
-+
-+#include "include/logger_interface.h"
-+#include "include/fixed31_32.h"
-+#include "basics/conversion.h"
-+
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+#include "dce80_ipp.h"
-+#include "dce110/dce110_ipp.h"
-+#include "gamma_types.h"
-+
-+#define DCP_REG(reg)\
-+ (reg + ipp80->offsets.dcp_offset)
-+
-+enum {
-+ MAX_INPUT_LUT_ENTRY = 256
-+};
-+
-+
-+/*PROTOTYPE DECLARATIONS*/
-+
-+
-+static void set_legacy_input_gamma_mode(
-+ struct dce110_ipp *ipp80,
-+ bool is_legacy);
-+
-+
-+
-+void dce80_ipp_set_legacy_input_gamma_mode(
-+ struct input_pixel_processor *ipp,
-+ bool is_legacy)
-+{
-+ struct dce110_ipp *ipp80 = TO_DCE80_IPP(ipp);
-+
-+ set_legacy_input_gamma_mode(ipp80, is_legacy);
-+}
-+
-+
-+static void set_legacy_input_gamma_mode(
-+ struct dce110_ipp *ipp80,
-+ bool is_legacy)
-+{
-+ const uint32_t addr = DCP_REG(mmINPUT_GAMMA_CONTROL);
-+ uint32_t value = dm_read_reg(ipp80->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ !is_legacy,
-+ INPUT_GAMMA_CONTROL,
-+ GRPH_INPUT_GAMMA_MODE);
-+
-+ dm_write_reg(ipp80->base.ctx, addr, value);
-+}
-+
-+
-+
-+
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_link_encoder.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_link_encoder.c
-new file mode 100644
-index 0000000..5288436
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_link_encoder.c
-@@ -0,0 +1,329 @@
-+/*
-+ * 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 "dm_services.h"
-+#include "core_types.h"
-+#include "dce80_link_encoder.h"
-+#include "stream_encoder.h"
-+#include "../dce110/dce110_link_encoder.h"
-+#include "i2caux_interface.h"
-+
-+/* TODO: change to dce80 header file */
-+#include "dce/dce_11_0_d.h"
-+#include "dce/dce_11_0_sh_mask.h"
-+#include "dce/dce_11_0_enum.h"
-+
-+#define LINK_REG(reg)\
-+ (enc110->link_regs->reg)
-+
-+#define DCE8_UNIPHY_MAX_PIXEL_CLK_IN_KHZ 297000
-+
-+#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 DCE80_DIG_FE_SOURCE_SELECT_INVALID 0x0
-+#define DCE80_DIG_FE_SOURCE_SELECT_DIGA 0x01
-+#define DCE80_DIG_FE_SOURCE_SELECT_DIGB 0x02
-+#define DCE80_DIG_FE_SOURCE_SELECT_DIGC 0x04
-+#define DCE80_DIG_FE_SOURCE_SELECT_DIGD 0x08
-+#define DCE80_DIG_FE_SOURCE_SELECT_DIGE 0x10
-+#define DCE80_DIG_FE_SOURCE_SELECT_DIGF 0x20
-+
-+/* 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
-+
-+enum {
-+ DP_MST_UPDATE_MAX_RETRY = 50
-+};
-+
-+static enum bp_result link_transmitter_control(
-+ struct dce110_link_encoder *enc110,
-+ struct bp_transmitter_control *cntl)
-+{
-+ enum bp_result result;
-+ struct dc_bios *bp = dal_adapter_service_get_bios_parser(
-+ enc110->base.adapter_service);
-+
-+ result = bp->funcs->transmitter_control(bp, cntl);
-+
-+ return result;
-+}
-+
-+static void dce80_link_encoder_enable_tmds_output(
-+ struct link_encoder *enc,
-+ enum clock_source_id clock_source,
-+ enum dc_color_depth color_depth,
-+ bool hdmi,
-+ bool dual_link,
-+ uint32_t pixel_clock)
-+{
-+ struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
-+ struct dc_context *ctx = enc110->base.ctx;
-+ struct bp_transmitter_control cntl = { 0 };
-+ enum bp_result result;
-+
-+ /* Enable the PHY */
-+
-+ cntl.action = TRANSMITTER_CONTROL_ENABLE;
-+ cntl.engine_id = enc->preferred_engine;
-+ cntl.transmitter = enc110->base.transmitter;
-+ cntl.pll_id = clock_source;
-+ if (hdmi) {
-+ cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A;
-+ cntl.lanes_number = 4;
-+ } else if (dual_link) {
-+ cntl.signal = SIGNAL_TYPE_DVI_DUAL_LINK;
-+ cntl.lanes_number = 8;
-+ } else {
-+ cntl.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
-+ cntl.lanes_number = 4;
-+ }
-+ cntl.hpd_sel = enc110->base.hpd_source;
-+
-+ cntl.pixel_clock = pixel_clock;
-+ cntl.color_depth = color_depth;
-+
-+ result = link_transmitter_control(enc110, &cntl);
-+
-+ if (result != BP_RESULT_OK) {
-+ dal_logger_write(ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_ENCODER,
-+ "%s: Failed to execute VBIOS command table!\n",
-+ __func__);
-+ BREAK_TO_DEBUGGER();
-+ }
-+}
-+
-+static void configure_encoder(
-+ struct dce110_link_encoder *enc110,
-+ const struct dc_link_settings *link_settings)
-+{
-+ struct dc_context *ctx = enc110->base.ctx;
-+ uint32_t addr;
-+ uint32_t value;
-+
-+ /* set number of lanes */
-+ addr = LINK_REG(DP_CONFIG);
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(value, link_settings->lane_count - LANE_COUNT_ONE,
-+ DP_CONFIG, DP_UDI_LANES);
-+ dm_write_reg(ctx, addr, value);
-+
-+}
-+
-+/* enables DP PHY output */
-+static void dce80_link_encoder_enable_dp_output(
-+ struct link_encoder *enc,
-+ const struct dc_link_settings *link_settings,
-+ enum clock_source_id clock_source)
-+{
-+ struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc);
-+ struct dc_context *ctx = enc110->base.ctx;
-+ struct bp_transmitter_control cntl = { 0 };
-+ enum bp_result result;
-+
-+ /* 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.
-+ */
-+ configure_encoder(enc110, link_settings);
-+
-+ cntl.action = TRANSMITTER_CONTROL_ENABLE;
-+ cntl.engine_id = enc->preferred_engine;
-+ cntl.transmitter = enc110->base.transmitter;
-+ cntl.pll_id = clock_source;
-+ cntl.signal = SIGNAL_TYPE_DISPLAY_PORT;
-+ cntl.lanes_number = link_settings->lane_count;
-+ cntl.hpd_sel = enc110->base.hpd_source;
-+ cntl.pixel_clock = link_settings->link_rate
-+ * LINK_RATE_REF_FREQ_IN_KHZ;
-+ /* TODO: check if undefined works */
-+ cntl.color_depth = COLOR_DEPTH_UNDEFINED;
-+
-+ result = link_transmitter_control(enc110, &cntl);
-+
-+ if (result != BP_RESULT_OK) {
-+ dal_logger_write(ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_ENCODER,
-+ "%s: Failed to execute VBIOS command table!\n",
-+ __func__);
-+ BREAK_TO_DEBUGGER();
-+ }
-+}
-+
-+static struct link_encoder_funcs dce80_lnk_enc_funcs = {
-+ .validate_output_with_stream =
-+ dce110_link_encoder_validate_output_with_stream,
-+ .hw_init = dce110_link_encoder_hw_init,
-+ .setup = dce110_link_encoder_setup,
-+ .enable_tmds_output = dce80_link_encoder_enable_tmds_output,
-+ .enable_dp_output = dce80_link_encoder_enable_dp_output,
-+ .enable_dp_mst_output = dce110_link_encoder_enable_dp_mst_output,
-+ .disable_output = dce110_link_encoder_disable_output,
-+ .dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings,
-+ .dp_set_phy_pattern = dce110_link_encoder_dp_set_phy_pattern,
-+ .update_mst_stream_allocation_table =
-+ dce110_link_encoder_update_mst_stream_allocation_table,
-+ .set_lcd_backlight_level = dce110_link_encoder_set_lcd_backlight_level,
-+ .backlight_control = dce110_link_encoder_edp_backlight_control,
-+ .power_control = dce110_link_encoder_edp_power_control,
-+ .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe
-+};
-+
-+
-+bool dce80_link_encoder_construct(
-+ struct dce110_link_encoder *enc110,
-+ const struct encoder_init_data *init_data,
-+ const struct dce110_link_enc_registers *link_regs,
-+ const struct dce110_link_enc_aux_registers *aux_regs,
-+ const struct dce110_link_enc_bl_registers *bl_regs)
-+{
-+ struct graphics_object_encoder_cap_info enc_cap_info = {0};
-+
-+ enc110->base.funcs = &dce80_lnk_enc_funcs;
-+ enc110->base.ctx = init_data->ctx;
-+ enc110->base.id = init_data->encoder;
-+
-+ enc110->base.hpd_source = init_data->hpd_source;
-+ enc110->base.connector = init_data->connector;
-+ enc110->base.input_signals = SIGNAL_TYPE_ALL;
-+
-+ enc110->base.adapter_service = init_data->adapter_service;
-+
-+ enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
-+
-+ enc110->base.features.flags.raw = 0;
-+
-+ enc110->base.transmitter = init_data->transmitter;
-+
-+ enc110->base.features.flags.bits.IS_AUDIO_CAPABLE = true;
-+
-+ enc110->base.features.max_pixel_clock = DCE8_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))
-+ enc110->base.features.flags.bits.
-+ DP_SINK_DETECT_POLL_DATA_PIN = true;
-+
-+ enc110->base.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
-+ */
-+
-+ enc110->link_regs = link_regs;
-+ enc110->aux_regs = aux_regs;
-+ enc110->bl_regs = bl_regs;
-+
-+ switch (enc110->base.transmitter) {
-+ case TRANSMITTER_UNIPHY_A:
-+ enc110->base.preferred_engine = ENGINE_ID_DIGA;
-+ break;
-+ case TRANSMITTER_UNIPHY_B:
-+ enc110->base.preferred_engine = ENGINE_ID_DIGB;
-+
-+ break;
-+ case TRANSMITTER_UNIPHY_C:
-+ enc110->base.preferred_engine = ENGINE_ID_DIGC;
-+ break;
-+ case TRANSMITTER_UNIPHY_D:
-+ enc110->base.preferred_engine = ENGINE_ID_DIGD;
-+ break;
-+ case TRANSMITTER_UNIPHY_E:
-+ enc110->base.preferred_engine = ENGINE_ID_DIGE;
-+ break;
-+ case TRANSMITTER_UNIPHY_F:
-+ enc110->base.preferred_engine = ENGINE_ID_DIGF;
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false);
-+ enc110->base.preferred_engine = ENGINE_ID_UNKNOWN;
-+ break;
-+ }
-+
-+ 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);
-+
-+ /* Override features with DCE-specific values */
-+ if (dal_adapter_service_get_encoder_cap_info(
-+ enc110->base.adapter_service,
-+ enc110->base.id, &enc_cap_info))
-+ enc110->base.features.flags.bits.IS_HBR2_CAPABLE =
-+ enc_cap_info.dp_hbr2_cap;
-+
-+ /* test pattern 3 support */
-+ enc110->base.features.flags.bits.IS_TPS3_CAPABLE = true;
-+ enc110->base.features.max_deep_color = COLOR_DEPTH_121212;
-+
-+ enc110->base.features.flags.bits.IS_Y_ONLY_CAPABLE =
-+ dal_adapter_service_is_feature_supported(
-+ FEATURE_SUPPORT_DP_Y_ONLY);
-+
-+ enc110->base.features.flags.bits.IS_YCBCR_CAPABLE =
-+ dal_adapter_service_is_feature_supported(
-+ FEATURE_SUPPORT_DP_YUV);
-+
-+ return true;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_link_encoder.h b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_link_encoder.h
-new file mode 100644
-index 0000000..b894643
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_link_encoder.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 __DC_LINK_ENCODER__DCE80_H__
-+#define __DC_LINK_ENCODER__DCE80_H__
-+
-+#include "inc/link_encoder.h"
-+#include "../dce110/dce110_link_encoder.h"
-+
-+bool dce80_link_encoder_construct(
-+ struct dce110_link_encoder *enc110,
-+ const struct encoder_init_data *init_data,
-+ const struct dce110_link_enc_registers *link_regs,
-+ const struct dce110_link_enc_aux_registers *aux_regs,
-+ const struct dce110_link_enc_bl_registers *bl_regs);
-+
-+#endif /* __DC_LINK_ENCODER__DCE80_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c
-new file mode 100644
-index 0000000..a8e9961
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.c
-@@ -0,0 +1,217 @@
-+/*
-+ * 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_DCE80_H__
-+
-+#define __DC_MEM_INPUT_DCE80_H__
-+
-+#include "dm_services.h"
-+
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+/* TODO: this needs to be looked at, used by Stella's workaround*/
-+#include "gmc/gmc_7_1_d.h"
-+#include "gmc/gmc_7_1_sh_mask.h"
-+
-+#include "include/logger_interface.h"
-+#include "adapter_service_interface.h"
-+#include "inc/bandwidth_calcs.h"
-+
-+#include "../dce110/dce110_mem_input.h"
-+#include "dce80_mem_input.h"
-+
-+
-+#define MAX_WATERMARK 0xFFFF
-+#define SAFE_NBP_MARK 0x7FFF
-+
-+#define DCP_REG(reg) (reg + mem_input80->offsets.dcp)
-+#define DMIF_REG(reg) (reg + mem_input80->offsets.dmif)
-+#define PIPE_REG(reg) (reg + mem_input80->offsets.pipe)
-+
-+static uint32_t get_dmif_switch_time_us(
-+ uint32_t h_total,
-+ uint32_t v_total,
-+ uint32_t pix_clk_khz)
-+{
-+ 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 (!h_total || v_total || !pix_clk_khz)
-+ return single_frame_time_multiplier * min_single_frame_time_us;
-+
-+ /*TODO: should we use pixel format normalized pixel clock here?*/
-+ pixels_per_second = pix_clk_khz * 1000;
-+ pixels_per_frame = h_total * 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;
-+}
-+
-+static void allocate_mem_input(
-+ struct mem_input *mi,
-+ uint32_t h_total,
-+ uint32_t v_total,
-+ uint32_t pix_clk_khz,
-+ uint32_t total_targets_num)
-+{
-+ const uint32_t retry_delay = 10;
-+ uint32_t retry_count = get_dmif_switch_time_us(
-+ h_total,
-+ v_total,
-+ pix_clk_khz) / retry_delay;
-+
-+ struct dce110_mem_input *bm80 = TO_DCE110_MEM_INPUT(mi);
-+ uint32_t addr = bm80->offsets.pipe + mmPIPE0_DMIF_BUFFER_CONTROL;
-+ uint32_t value;
-+ uint32_t field;
-+
-+ if (bm80->supported_stutter_mode
-+ & STUTTER_MODE_NO_DMIF_BUFFER_ALLOCATION)
-+ goto register_underflow_int;
-+
-+ /*Allocate DMIF buffer*/
-+ value = dm_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);
-+
-+ dm_write_reg(mi->ctx, addr, value);
-+
-+ do {
-+ value = dm_read_reg(mi->ctx, addr);
-+ field = get_reg_field_value(
-+ value,
-+ PIPE0_DMIF_BUFFER_CONTROL,
-+ DMIF_BUFFERS_ALLOCATION_COMPLETED);
-+
-+ if (field)
-+ break;
-+
-+ dm_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 = dm_read_reg(mi->ctx, addr);
-+ if (total_targets_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);
-+ dm_write_reg(mi->ctx, addr, value);
-+
-+register_underflow_int:
-+ /*todo*/;
-+ /*register_interrupt(bm80, irq_source, ctrl_id);*/
-+}
-+
-+static struct mem_input_funcs dce80_mem_input_funcs = {
-+ .mem_input_program_display_marks =
-+ dce110_mem_input_program_display_marks,
-+ .allocate_mem_input = allocate_mem_input,
-+ .free_mem_input =
-+ dce110_free_mem_input,
-+ .mem_input_program_surface_flip_and_addr =
-+ dce110_mem_input_program_surface_flip_and_addr,
-+ .mem_input_program_surface_config =
-+ dce110_mem_input_program_surface_config,
-+};
-+
-+/*****************************************/
-+/* Constructor, Destructor */
-+/*****************************************/
-+
-+bool dce80_mem_input_construct(
-+ struct dce110_mem_input *mem_input80,
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_mem_input_reg_offsets *offsets)
-+{
-+
-+ mem_input80->base.funcs = &dce80_mem_input_funcs;
-+ mem_input80->base.ctx = ctx;
-+
-+ mem_input80->base.inst = inst;
-+
-+ mem_input80->offsets = *offsets;
-+
-+ mem_input80->supported_stutter_mode = 0;
-+ dal_adapter_service_get_feature_value(FEATURE_STUTTER_MODE,
-+ &(mem_input80->supported_stutter_mode),
-+ sizeof(mem_input80->supported_stutter_mode));
-+
-+ return true;
-+}
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.h b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.h
-new file mode 100644
-index 0000000..1d299da
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_mem_input.h
-@@ -0,0 +1,41 @@
-+/* 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_DCE80_H__
-+#define __DC_MEM_INPUT_DCE80_H__
-+
-+#include "inc/mem_input.h"
-+
-+bool dce80_mem_input_construct(
-+ struct dce110_mem_input *mem_input80,
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_mem_input_reg_offsets *offsets);
-+
-+
-+enum dc_status dce_base_validate_mapped_resource(
-+ const struct dc *dc,
-+ struct validate_context *context);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp.c
-new file mode 100644
-index 0000000..82c98a1
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp.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 "dm_services.h"
-+
-+/* include DCE8 register header files */
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+#include "dce80_opp.h"
-+
-+#define FROM_OPP(opp)\
-+ container_of(opp, struct dce80_opp, base)
-+
-+enum {
-+ MAX_LUT_ENTRY = 256,
-+ MAX_NUMBER_OF_ENTRIES = 256
-+};
-+
-+static const struct dce80_opp_reg_offsets reg_offsets[] = {
-+{
-+ .fmt_offset = (mmFMT0_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .crtc_offset = (mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL -
-+ mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp_offset = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{ .fmt_offset = (mmFMT1_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .crtc_offset = (mmCRTC1_DCFE_MEM_LIGHT_SLEEP_CNTL -
-+ mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp_offset = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{ .fmt_offset = (mmFMT2_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .crtc_offset = (mmCRTC2_DCFE_MEM_LIGHT_SLEEP_CNTL -
-+ mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp_offset = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{
-+ .fmt_offset = (mmFMT3_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .crtc_offset = (mmCRTC3_DCFE_MEM_LIGHT_SLEEP_CNTL -
-+ mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp_offset = (mmDCP3_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{
-+ .fmt_offset = (mmFMT4_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .crtc_offset = (mmCRTC4_DCFE_MEM_LIGHT_SLEEP_CNTL -
-+ mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp_offset = (mmDCP4_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{
-+ .fmt_offset = (mmFMT5_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .crtc_offset = (mmCRTC5_DCFE_MEM_LIGHT_SLEEP_CNTL -
-+ mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp_offset = (mmDCP5_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+}
-+};
-+
-+
-+
-+static struct opp_funcs funcs = {
-+ .opp_power_on_regamma_lut = dce80_opp_power_on_regamma_lut,
-+ .opp_program_bit_depth_reduction =
-+ dce80_opp_program_bit_depth_reduction,
-+ .opp_program_clamping_and_pixel_encoding =
-+ dce80_opp_program_clamping_and_pixel_encoding,
-+ .opp_set_csc_adjustment = dce80_opp_set_csc_adjustment,
-+ .opp_set_csc_default = dce80_opp_set_csc_default,
-+ .opp_set_dyn_expansion = dce80_opp_set_dyn_expansion,
-+ .opp_program_regamma_pwl = dce80_opp_program_regamma_pwl,
-+ .opp_set_regamma_mode = dce80_opp_set_regamma_mode,
-+ .opp_destroy = dce80_opp_destroy,
-+};
-+
-+/*****************************************/
-+/* Constructor, Destructor */
-+/*****************************************/
-+
-+bool dce80_opp_construct(struct dce80_opp *opp80,
-+ struct dc_context *ctx,
-+ uint32_t inst)
-+{
-+ if (inst >= ARRAY_SIZE(reg_offsets))
-+ return false;
-+
-+ opp80->base.funcs = &funcs;
-+
-+ opp80->base.ctx = ctx;
-+
-+ opp80->base.inst = inst;
-+
-+ opp80->offsets = reg_offsets[inst];
-+
-+ return true;
-+}
-+
-+void dce80_opp_destroy(struct output_pixel_processor **opp)
-+{
-+ dm_free((*opp)->ctx, FROM_OPP(*opp));
-+ *opp = NULL;
-+}
-+
-+struct output_pixel_processor *dce80_opp_create(
-+ struct dc_context *ctx,
-+ uint32_t inst)
-+{
-+ struct dce80_opp *opp =
-+ dm_alloc(ctx, sizeof(struct dce80_opp));
-+
-+ if (!opp)
-+ return NULL;
-+
-+ if (dce80_opp_construct(opp,
-+ ctx, inst))
-+ return &opp->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(ctx, opp);
-+ return NULL;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp.h b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp.h
-new file mode 100644
-index 0000000..d414f50
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp.h
-@@ -0,0 +1,130 @@
-+/* 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_DCE80_H__
-+#define __DC_OPP_DCE80_H__
-+
-+#include "dc_types.h"
-+#include "inc/opp.h"
-+#include "gamma_types.h"
-+
-+struct gamma_parameters;
-+
-+struct dce80_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;
-+ 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_DCE80_OPP(opp)\
-+ container_of(opp, struct dce80_opp, base)
-+
-+struct dce80_opp_reg_offsets {
-+ uint32_t fmt_offset;
-+ uint32_t dcp_offset;
-+ uint32_t crtc_offset;
-+};
-+
-+struct dce80_opp {
-+ struct output_pixel_processor base;
-+ struct dce80_opp_reg_offsets offsets;
-+ struct dce80_regamma regamma;
-+};
-+
-+bool dce80_opp_construct(struct dce80_opp *opp80,
-+ struct dc_context *ctx,
-+ uint32_t inst);
-+
-+void dce80_opp_destroy(struct output_pixel_processor **opp);
-+
-+struct output_pixel_processor *dce80_opp_create(
-+ struct dc_context *ctx,
-+ uint32_t inst);
-+
-+/* REGAMMA RELATED */
-+void dce80_opp_power_on_regamma_lut(
-+ struct output_pixel_processor *opp,
-+ bool power_on);
-+
-+bool dce80_opp_program_regamma_pwl(
-+ struct output_pixel_processor *opp,
-+ const struct regamma_params *pamras);
-+
-+void dce80_opp_set_regamma_mode(struct output_pixel_processor *opp,
-+ enum opp_regamma mode);
-+
-+void dce80_opp_set_csc_adjustment(
-+ struct output_pixel_processor *opp,
-+ const struct grph_csc_adjustment *adjust);
-+
-+void dce80_opp_set_csc_default(
-+ struct output_pixel_processor *opp,
-+ const struct default_adjustment *default_adjust);
-+
-+/* FORMATTER RELATED */
-+void dce80_opp_program_bit_depth_reduction(
-+ struct output_pixel_processor *opp,
-+ const struct bit_depth_reduction_params *params);
-+
-+void dce80_opp_program_clamping_and_pixel_encoding(
-+ struct output_pixel_processor *opp,
-+ const struct clamping_and_pixel_encoding_params *params);
-+
-+
-+void dce80_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/dce80/dce80_opp_csc.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp_csc.c
-new file mode 100644
-index 0000000..90662ae
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp_csc.c
-@@ -0,0 +1,905 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+#include "dce80_opp.h"
-+#include "basics/conversion.h"
-+
-+/* include DCE8 register header files */
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+#define DCP_REG(reg)\
-+ (reg + opp80->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 dce80_opp *opp80,
-+ const struct out_csc_color_matrix *tbl_entry,
-+ enum grph_color_adjust_option options)
-+{
-+ struct dc_context *ctx = opp80->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);
-+
-+ dm_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);
-+
-+ dm_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);
-+
-+ dm_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);
-+
-+ dm_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);
-+
-+ dm_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);
-+
-+ dm_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 dce80_opp *opp80,
-+ 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(
-+ opp80, &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 dce80_opp *opp80,
-+ 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);
-+
-+ dm_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];
-+
-+ dm_memset(&reg_matrix, 0, sizeof(struct out_csc_color_matrix));
-+
-+ setup_reg_format(matrix, reg_matrix.regval);
-+
-+ program_color_matrix(opp80, &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 dce80_opp *opp80,
-+ 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);
-+
-+ dm_memset(&reg_matrix, 0, sizeof(struct out_csc_color_matrix));
-+
-+ setup_reg_format(matrix, reg_matrix.regval);
-+
-+ program_color_matrix(opp80, &reg_matrix, GRPH_COLOR_MATRIX_SW);
-+}
-+
-+static bool configure_graphics_mode(
-+ struct dce80_opp *opp80,
-+ enum csc_color_mode config,
-+ enum graphics_csc_adjust_type csc_adjust_type,
-+ enum color_space color_space)
-+{
-+ struct dc_context *ctx = opp80->base.ctx;
-+ uint32_t addr = DCP_REG(mmOUTPUT_CSC_CONTROL);
-+ uint32_t value = dm_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);
-+ dm_write_reg(ctx, addr, value);
-+
-+ return true;
-+}
-+
-+void dce80_opp_set_csc_adjustment(
-+ struct output_pixel_processor *opp,
-+ const struct grph_csc_adjustment *adjust)
-+{
-+ struct dce80_opp *opp80 = TO_DCE80_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(opp80, adjust);
-+ break;
-+ case COLOR_SPACE_SRGB_LIMITED_RANGE:
-+ set_rgb_limited_range_adjustment(
-+ opp80, 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(opp80, adjust);
-+ break;
-+ default:
-+ set_rgb_adjustment_legacy(opp80, adjust);
-+ break;
-+ }
-+
-+ /* We did everything ,now program DxOUTPUT_CSC_CONTROL */
-+ configure_graphics_mode(opp80, config, adjust->csc_adjust_type,
-+ adjust->c_space);
-+}
-+
-+void dce80_opp_set_csc_default(
-+ struct output_pixel_processor *opp,
-+ const struct default_adjustment *default_adjust)
-+{
-+ struct dce80_opp *opp80 = TO_DCE80_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(opp80, 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(opp80, config,
-+ default_adjust->csc_adjust_type,
-+ default_adjust->color_space);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp_formatter.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp_formatter.c
-new file mode 100644
-index 0000000..9d0a214
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp_formatter.c
-@@ -0,0 +1,577 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+#include "dce80_opp.h"
-+
-+#define FMT_REG(reg)\
-+ (reg + opp80->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 DCE8 power saving reason.
-+ */
-+static void set_truncation(
-+ struct dce80_opp *opp80,
-+ const struct bit_depth_reduction_params *params)
-+{
-+ uint32_t value = 0;
-+ uint32_t addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
-+
-+ /*Disable truncation*/
-+ value = dm_read_reg(opp80->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);
-+
-+ dm_write_reg(opp80->base.ctx, addr, value);
-+
-+ /* no 10bpc trunc on DCE8*/
-+ 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);
-+
-+ dm_write_reg(opp80->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 dce80_opp *opp80,
-+ const struct bit_depth_reduction_params *params)
-+{
-+ uint32_t addr = FMT_REG(mmFMT_BIT_DEPTH_CONTROL);
-+ uint32_t depth_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 = dm_read_reg(opp80->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);
-+
-+ dm_write_reg(opp80->base.ctx, addr, depth_cntl_value);
-+
-+ /* no 10bpc on DCE8*/
-+ if (params->flags.SPATIAL_DITHER_ENABLED == 0 ||
-+ params->flags.SPATIAL_DITHER_DEPTH == 2)
-+ return;
-+
-+ /*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);
-+ dm_write_reg(opp80->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);
-+ dm_write_reg(opp80->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);
-+ dm_write_reg(opp80->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);
-+ dm_write_reg(opp80->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 dce80_opp *opp80,
-+ 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 = dm_read_reg(opp80->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);
-+
-+ dm_write_reg(opp80->base.ctx, addr, value);
-+
-+ /* no 10bpc dither on DCE8*/
-+ 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);
-+ dm_write_reg(opp80->base.ctx, addr, 0);
-+ /*Set s matrix*/
-+ addr = FMT_REG(
-+ mmFMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_S_MATRIX);
-+ dm_write_reg(opp80->base.ctx, addr, 0);
-+ /*Set t matrix*/
-+ addr = FMT_REG(
-+ mmFMT_TEMPORAL_DITHER_PROGRAMMABLE_PATTERN_T_MATRIX);
-+ dm_write_reg(opp80->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);
-+ dm_write_reg(opp80->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 dce80_opp *opp80,
-+ 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 = dm_read_reg(opp80->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);
-+ dm_write_reg(opp80->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);
-+ dm_write_reg(opp80->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);
-+ dm_write_reg(opp80->base.ctx, addr, blue_clamp_value);
-+
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ addr = FMT_REG(mmFMT_CLAMP_CNTL);
-+ /*Set clamp control*/
-+ dm_write_reg(opp80->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 dce80_opp *opp80,
-+ 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 = dm_read_reg(opp80->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);
-+ }
-+ dm_write_reg(opp80->base.ctx, addr, fmt_cntl_value);
-+
-+}
-+
-+void dce80_opp_program_bit_depth_reduction(
-+ struct output_pixel_processor *opp,
-+ const struct bit_depth_reduction_params *params)
-+{
-+ struct dce80_opp *opp80 = TO_DCE80_OPP(opp);
-+
-+ set_truncation(opp80, params);
-+ set_spatial_dither(opp80, params);
-+ set_temporal_dither(opp80, params);
-+}
-+
-+void dce80_opp_program_clamping_and_pixel_encoding(
-+ struct output_pixel_processor *opp,
-+ const struct clamping_and_pixel_encoding_params *params)
-+{
-+ struct dce80_opp *opp80 = TO_DCE80_OPP(opp);
-+
-+ set_clamping(opp80, params);
-+ set_pixel_encoding(opp80, params);
-+}
-+
-+void dce80_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 dce80_opp *opp80 = TO_DCE80_OPP(opp);
-+ uint32_t value;
-+ bool enable_dyn_exp = false;
-+ uint32_t addr = FMT_REG(mmFMT_DYNAMIC_EXP_CNTL);
-+
-+ value = dm_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;
-+ }
-+ }
-+
-+ dm_write_reg(opp->ctx, addr, value);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp_regamma.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp_regamma.c
-new file mode 100644
-index 0000000..ef95e98
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_opp_regamma.c
-@@ -0,0 +1,546 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+/* include DCE8 register header files */
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+#include "dce80_opp.h"
-+#include "gamma_types.h"
-+
-+#define DCP_REG(reg)\
-+ (reg + opp80->offsets.dcp_offset)
-+
-+#define DCFE_REG(reg)\
-+ (reg + opp80->offsets.crtc_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;
-+};
-+
-+/*
-+ *****************************************************************************
-+ * 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 dce80_opp *opp80, const struct regamma_params *params)
-+{
-+ const struct gamma_curve *curve;
-+ uint32_t value = 0;
-+
-+ {
-+ set_reg_field_value(
-+ value,
-+ params->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);
-+
-+ dm_write_reg(opp80->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_START_CNTL),
-+ value);
-+ }
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ params->arr_points[0].custom_float_slope,
-+ REGAMMA_CNTLA_SLOPE_CNTL,
-+ REGAMMA_CNTLA_EXP_REGION_LINEAR_SLOPE);
-+
-+ dm_write_reg(opp80->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_SLOPE_CNTL), value);
-+ }
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ params->arr_points[1].custom_float_x,
-+ REGAMMA_CNTLA_END_CNTL1,
-+ REGAMMA_CNTLA_EXP_REGION_END);
-+
-+ dm_write_reg(opp80->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_END_CNTL1), value);
-+ }
-+ {
-+ value = 0;
-+ set_reg_field_value(
-+ value,
-+ params->arr_points[2].custom_float_slope,
-+ REGAMMA_CNTLA_END_CNTL2,
-+ REGAMMA_CNTLA_EXP_REGION_END_BASE);
-+
-+ set_reg_field_value(
-+ value,
-+ params->arr_points[1].custom_float_y,
-+ REGAMMA_CNTLA_END_CNTL2,
-+ REGAMMA_CNTLA_EXP_REGION_END_SLOPE);
-+
-+ dm_write_reg(opp80->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_END_CNTL2), value);
-+ }
-+
-+ curve = params->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);
-+
-+ dm_write_reg(
-+ opp80->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);
-+
-+ dm_write_reg(opp80->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);
-+
-+ dm_write_reg(opp80->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);
-+
-+ dm_write_reg(opp80->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);
-+
-+ dm_write_reg(opp80->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);
-+
-+ dm_write_reg(opp80->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);
-+
-+ dm_write_reg(opp80->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);
-+
-+ dm_write_reg(opp80->base.ctx,
-+ DCP_REG(mmREGAMMA_CNTLA_REGION_14_15),
-+ value);
-+ }
-+}
-+
-+static void program_pwl(
-+ struct dce80_opp *opp80,
-+ const struct regamma_params *params)
-+{
-+ uint32_t value;
-+
-+ {
-+ uint8_t max_tries = 10;
-+ uint8_t counter = 0;
-+
-+ /* Power on LUT memory */
-+ value = dm_read_reg(opp80->base.ctx,
-+ DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL));
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DCFE_MEM_LIGHT_SLEEP_CNTL,
-+ REGAMMA_LUT_LIGHT_SLEEP_DIS);
-+
-+ dm_write_reg(opp80->base.ctx,
-+ DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL), value);
-+
-+ while (counter < max_tries) {
-+ value =
-+ dm_read_reg(
-+ opp80->base.ctx,
-+ DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL));
-+
-+ if (get_reg_field_value(
-+ value,
-+ DCFE_MEM_LIGHT_SLEEP_CNTL,
-+ REGAMMA_LUT_MEM_PWR_STATE) == 0)
-+ break;
-+
-+ ++counter;
-+ }
-+
-+ if (counter == max_tries) {
-+ dal_logger_write(opp80->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);
-+
-+ dm_write_reg(opp80->base.ctx,
-+ DCP_REG(mmREGAMMA_LUT_WRITE_EN_MASK), value);
-+ dm_write_reg(opp80->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;
-+
-+ const struct pwl_result_data *rgb =
-+ params->rgb_resulted;
-+
-+ while (i != params->hw_points_num) {
-+ dm_write_reg(opp80->base.ctx, addr, rgb->red_reg);
-+ dm_write_reg(opp80->base.ctx, addr, rgb->green_reg);
-+ dm_write_reg(opp80->base.ctx, addr, rgb->blue_reg);
-+
-+ dm_write_reg(opp80->base.ctx, addr,
-+ rgb->delta_red_reg);
-+ dm_write_reg(opp80->base.ctx, addr,
-+ rgb->delta_green_reg);
-+ dm_write_reg(opp80->base.ctx, addr,
-+ rgb->delta_blue_reg);
-+
-+ ++rgb;
-+ ++i;
-+ }
-+ }
-+
-+ /* we are done with DCP LUT memory; re-enable low power mode */
-+ value = dm_read_reg(opp80->base.ctx,
-+ DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL));
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DCFE_MEM_LIGHT_SLEEP_CNTL,
-+ REGAMMA_LUT_LIGHT_SLEEP_DIS);
-+
-+ dm_write_reg(opp80->base.ctx, DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL),
-+ value);
-+}
-+
-+
-+void dce80_opp_power_on_regamma_lut(
-+ struct output_pixel_processor *opp,
-+ bool power_on)
-+{
-+ struct dce80_opp *opp80 = TO_DCE80_OPP(opp);
-+
-+ uint32_t value =
-+ dm_read_reg(opp->ctx, DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL));
-+
-+ set_reg_field_value(
-+ value,
-+ power_on,
-+ DCFE_MEM_LIGHT_SLEEP_CNTL,
-+ REGAMMA_LUT_LIGHT_SLEEP_DIS);
-+
-+ set_reg_field_value(
-+ value,
-+ power_on,
-+ DCFE_MEM_LIGHT_SLEEP_CNTL,
-+ DCP_LUT_LIGHT_SLEEP_DIS);
-+
-+ dm_write_reg(opp->ctx, DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL), value);
-+}
-+
-+bool dce80_opp_program_regamma_pwl(
-+ struct output_pixel_processor *opp,
-+ const struct regamma_params *params)
-+{
-+
-+ struct dce80_opp *opp80 = TO_DCE80_OPP(opp);
-+
-+ regamma_config_regions_and_segments(opp80, params);
-+
-+ program_pwl(opp80, params);
-+
-+ return true;
-+}
-+
-+void dce80_opp_set_regamma_mode(struct output_pixel_processor *opp,
-+ enum opp_regamma mode)
-+{
-+ struct dce80_opp *opp80 = TO_DCE80_OPP(opp);
-+ uint32_t value = dm_read_reg(opp80->base.ctx,
-+ DCP_REG(mmREGAMMA_CONTROL));
-+
-+ set_reg_field_value(
-+ value,
-+ mode,
-+ REGAMMA_CONTROL,
-+ GRPH_REGAMMA_MODE);
-+
-+ dm_write_reg(opp80->base.ctx, DCP_REG(mmREGAMMA_CONTROL), value);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c
-new file mode 100644
-index 0000000..1eeb469
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.c
-@@ -0,0 +1,1267 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+#include "link_encoder.h"
-+#include "stream_encoder.h"
-+
-+#include "resource.h"
-+#include "include/irq_service_interface.h"
-+#include "../virtual/virtual_stream_encoder.h"
-+#include "dce110/dce110_timing_generator.h"
-+#include "dce110/dce110_mem_input.h"
-+#include "dce110/dce110_resource.h"
-+#include "dce80/dce80_timing_generator.h"
-+#include "dce80/dce80_link_encoder.h"
-+#include "dce110/dce110_link_encoder.h"
-+#include "dce80/dce80_mem_input.h"
-+#include "dce80/dce80_ipp.h"
-+#include "dce80/dce80_transform.h"
-+#include "dce110/dce110_stream_encoder.h"
-+#include "dce80/dce80_stream_encoder.h"
-+#include "dce80/dce80_opp.h"
-+#include "dce110/dce110_ipp.h"
-+#include "dce110/dce110_clock_source.h"
-+
-+#include "dce/dce_8_0_d.h"
-+
-+/* TODO remove this include */
-+
-+#ifndef mmDP_DPHY_INTERNAL_CTRL
-+#define mmDP_DPHY_INTERNAL_CTRL 0x1CDE
-+#define mmDP0_DP_DPHY_INTERNAL_CTRL 0x1CDE
-+#define mmDP1_DP_DPHY_INTERNAL_CTRL 0x1FDE
-+#define mmDP2_DP_DPHY_INTERNAL_CTRL 0x42DE
-+#define mmDP3_DP_DPHY_INTERNAL_CTRL 0x45DE
-+#define mmDP4_DP_DPHY_INTERNAL_CTRL 0x48DE
-+#define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4BDE
-+#define mmDP6_DP_DPHY_INTERNAL_CTRL 0x4EDE
-+#endif
-+
-+enum dce80_clk_src_array_id {
-+ DCE80_CLK_SRC_PLL0 = 0,
-+ DCE80_CLK_SRC_PLL1,
-+ DCE80_CLK_SRC_PLL2,
-+ DCE80_CLK_SRC_EXT,
-+
-+ DCE80_CLK_SRC_TOTAL
-+};
-+
-+#define DCE11_DIG_FE_CNTL 0x4a00
-+#define DCE11_DIG_BE_CNTL 0x4a47
-+#define DCE11_DP_SEC 0x4ac3
-+
-+static const struct dce110_timing_generator_offsets dce80_tg_offsets[] = {
-+ {
-+ .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
-+ .dcp = (mmGRPH_CONTROL - mmGRPH_CONTROL),
-+ .dmif = (mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL
-+ - mmDPG_WATERMARK_MASK_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
-+ .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .dmif = (mmDMIF_PG1_DPG_WATERMARK_MASK_CONTROL
-+ - mmDPG_WATERMARK_MASK_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
-+ .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .dmif = (mmDMIF_PG2_DPG_WATERMARK_MASK_CONTROL
-+ - mmDPG_WATERMARK_MASK_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
-+ .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .dmif = (mmDMIF_PG3_DPG_WATERMARK_MASK_CONTROL
-+ - mmDPG_WATERMARK_MASK_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
-+ .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .dmif = (mmDMIF_PG4_DPG_WATERMARK_MASK_CONTROL
-+ - mmDPG_WATERMARK_MASK_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
-+ .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .dmif = (mmDMIF_PG5_DPG_WATERMARK_MASK_CONTROL
-+ - mmDPG_WATERMARK_MASK_CONTROL),
-+ }
-+};
-+
-+static const struct dce110_mem_input_reg_offsets dce80_mi_reg_offsets[] = {
-+ {
-+ .dcp = (mmGRPH_CONTROL - mmGRPH_CONTROL),
-+ .dmif = (mmDMIF_PG0_DPG_WATERMARK_MASK_CONTROL
-+ - mmDPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE0_DMIF_BUFFER_CONTROL
-+ - mmPIPE0_DMIF_BUFFER_CONTROL),
-+ },
-+ {
-+ .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .dmif = (mmDMIF_PG1_DPG_WATERMARK_MASK_CONTROL
-+ - mmDPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE1_DMIF_BUFFER_CONTROL
-+ - mmPIPE0_DMIF_BUFFER_CONTROL),
-+ },
-+ {
-+ .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .dmif = (mmDMIF_PG2_DPG_WATERMARK_MASK_CONTROL
-+ - mmDPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE2_DMIF_BUFFER_CONTROL
-+ - mmPIPE0_DMIF_BUFFER_CONTROL),
-+ },
-+ {
-+ .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .dmif = (mmDMIF_PG3_DPG_WATERMARK_MASK_CONTROL
-+ - mmDPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE3_DMIF_BUFFER_CONTROL
-+ - mmPIPE0_DMIF_BUFFER_CONTROL),
-+ },
-+ {
-+ .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .dmif = (mmDMIF_PG4_DPG_WATERMARK_MASK_CONTROL
-+ - mmDPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE4_DMIF_BUFFER_CONTROL
-+ - mmPIPE0_DMIF_BUFFER_CONTROL),
-+ },
-+ {
-+ .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .dmif = (mmDMIF_PG5_DPG_WATERMARK_MASK_CONTROL
-+ - mmDPG_WATERMARK_MASK_CONTROL),
-+ .pipe = (mmPIPE5_DMIF_BUFFER_CONTROL
-+ - mmPIPE0_DMIF_BUFFER_CONTROL),
-+ }
-+};
-+
-+static const struct dce80_transform_reg_offsets dce80_xfm_offsets[] = {
-+{
-+ .scl_offset = (mmSCL_CONTROL - mmSCL_CONTROL),
-+ .crtc_offset = (mmDCFE_MEM_LIGHT_SLEEP_CNTL -
-+ mmDCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp_offset = (mmGRPH_CONTROL - mmGRPH_CONTROL),
-+ .lb_offset = (mmLB_DATA_FORMAT - mmLB_DATA_FORMAT),
-+},
-+{ .scl_offset = (mmSCL1_SCL_CONTROL - mmSCL_CONTROL),
-+ .crtc_offset = (mmCRTC1_DCFE_MEM_LIGHT_SLEEP_CNTL -
-+ mmDCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp_offset = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .lb_offset = (mmLB1_LB_DATA_FORMAT - mmLB_DATA_FORMAT),
-+},
-+{ .scl_offset = (mmSCL2_SCL_CONTROL - mmSCL_CONTROL),
-+ .crtc_offset = (mmCRTC2_DCFE_MEM_LIGHT_SLEEP_CNTL -
-+ mmDCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp_offset = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .lb_offset = (mmLB2_LB_DATA_FORMAT - mmLB_DATA_FORMAT),
-+},
-+{
-+ .scl_offset = (mmSCL3_SCL_CONTROL - mmSCL_CONTROL),
-+ .crtc_offset = (mmCRTC3_DCFE_MEM_LIGHT_SLEEP_CNTL -
-+ mmDCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp_offset = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .lb_offset = (mmLB3_LB_DATA_FORMAT - mmLB_DATA_FORMAT),
-+},
-+{
-+ .scl_offset = (mmSCL4_SCL_CONTROL - mmSCL_CONTROL),
-+ .crtc_offset = (mmCRTC4_DCFE_MEM_LIGHT_SLEEP_CNTL -
-+ mmDCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp_offset = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .lb_offset = (mmLB4_LB_DATA_FORMAT - mmLB_DATA_FORMAT),
-+},
-+{
-+ .scl_offset = (mmSCL5_SCL_CONTROL - mmSCL_CONTROL),
-+ .crtc_offset = (mmCRTC5_DCFE_MEM_LIGHT_SLEEP_CNTL -
-+ mmDCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp_offset = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .lb_offset = (mmLB5_LB_DATA_FORMAT - mmLB_DATA_FORMAT),
-+}
-+};
-+
-+static const struct dce110_ipp_reg_offsets ipp_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),
-+},
-+{
-+ .dcp_offset = (mmDCP3_CUR_CONTROL - mmDCP0_CUR_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP4_CUR_CONTROL - mmDCP0_CUR_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP5_CUR_CONTROL - mmDCP0_CUR_CONTROL),
-+}
-+};
-+
-+static const struct dce110_link_enc_bl_registers link_enc_bl_regs = {
-+ .BL_PWM_CNTL = mmBL_PWM_CNTL,
-+ .BL_PWM_GRP1_REG_LOCK = mmBL_PWM_GRP1_REG_LOCK,
-+ .BL_PWM_PERIOD_CNTL = mmBL_PWM_PERIOD_CNTL,
-+ .LVTMA_PWRSEQ_CNTL = mmLVTMA_PWRSEQ_CNTL,
-+ .LVTMA_PWRSEQ_STATE = mmLVTMA_PWRSEQ_STATE
-+};
-+
-+#define aux_regs(id)\
-+[id] = {\
-+ .AUX_CONTROL = mmDP_AUX ## id ## _AUX_CONTROL,\
-+ .AUX_DPHY_RX_CONTROL0 = mmDP_AUX ## id ## _AUX_DPHY_RX_CONTROL0\
-+}
-+
-+static const struct dce110_link_enc_aux_registers link_enc_aux_regs[] = {
-+ aux_regs(0),
-+ aux_regs(1),
-+ aux_regs(2),
-+ aux_regs(3),
-+ aux_regs(4),
-+ aux_regs(5)
-+};
-+
-+#define link_regs(id)\
-+[id] = {\
-+ .DIG_BE_CNTL = mmDIG ## id ## _DIG_BE_CNTL,\
-+ .DIG_BE_EN_CNTL = mmDIG ## id ## _DIG_BE_EN_CNTL,\
-+ .DP_CONFIG = mmDP ## id ## _DP_CONFIG,\
-+ .DP_DPHY_CNTL = mmDP ## id ## _DP_DPHY_CNTL,\
-+ .DP_DPHY_INTERNAL_CTRL = mmDP ## id ## _DP_DPHY_INTERNAL_CTRL,\
-+ .DP_DPHY_PRBS_CNTL = mmDP ## id ## _DP_DPHY_PRBS_CNTL,\
-+ .DP_DPHY_SYM0 = mmDP ## id ## _DP_DPHY_SYM0,\
-+ .DP_DPHY_SYM1 = mmDP ## id ## _DP_DPHY_SYM1,\
-+ .DP_DPHY_SYM2 = mmDP ## id ## _DP_DPHY_SYM2,\
-+ .DP_DPHY_TRAINING_PATTERN_SEL = mmDP ## id ## _DP_DPHY_TRAINING_PATTERN_SEL,\
-+ .DP_LINK_CNTL = mmDP ## id ## _DP_LINK_CNTL,\
-+ .DP_LINK_FRAMING_CNTL = mmDP ## id ## _DP_LINK_FRAMING_CNTL,\
-+ .DP_MSE_SAT0 = mmDP ## id ## _DP_MSE_SAT0,\
-+ .DP_MSE_SAT1 = mmDP ## id ## _DP_MSE_SAT1,\
-+ .DP_MSE_SAT2 = mmDP ## id ## _DP_MSE_SAT2,\
-+ .DP_MSE_SAT_UPDATE = mmDP ## id ## _DP_MSE_SAT_UPDATE,\
-+ .DP_SEC_CNTL = mmDP ## id ## _DP_SEC_CNTL,\
-+ .DP_VID_STREAM_CNTL = mmDP ## id ## _DP_VID_STREAM_CNTL\
-+}
-+
-+static const struct dce110_link_enc_registers link_enc_regs[] = {
-+ link_regs(0),
-+ link_regs(1),
-+ link_regs(2),
-+ link_regs(3),
-+ link_regs(4),
-+ link_regs(5)
-+};
-+
-+#define stream_enc_regs(id)\
-+[id] = {\
-+ .AFMT_AVI_INFO0 = mmDIG ## id ## _AFMT_AVI_INFO0,\
-+ .AFMT_AVI_INFO1 = mmDIG ## id ## _AFMT_AVI_INFO1,\
-+ .AFMT_AVI_INFO2 = mmDIG ## id ## _AFMT_AVI_INFO2,\
-+ .AFMT_AVI_INFO3 = mmDIG ## id ## _AFMT_AVI_INFO3,\
-+ .AFMT_GENERIC_0 = mmDIG ## id ## _AFMT_GENERIC_0,\
-+ .AFMT_GENERIC_7 = mmDIG ## id ## _AFMT_GENERIC_7,\
-+ .AFMT_GENERIC_HDR = mmDIG ## id ## _AFMT_GENERIC_HDR,\
-+ .AFMT_INFOFRAME_CONTROL0 = mmDIG ## id ## _AFMT_INFOFRAME_CONTROL0,\
-+ .AFMT_VBI_PACKET_CONTROL = mmDIG ## id ## _AFMT_VBI_PACKET_CONTROL,\
-+ .DIG_FE_CNTL = mmDIG ## id ## _DIG_FE_CNTL,\
-+ .DP_MSE_RATE_CNTL = mmDP ## id ## _DP_MSE_RATE_CNTL,\
-+ .DP_MSE_RATE_UPDATE = mmDP ## id ## _DP_MSE_RATE_UPDATE,\
-+ .DP_PIXEL_FORMAT = mmDP ## id ## _DP_PIXEL_FORMAT,\
-+ .DP_SEC_CNTL = mmDP ## id ## _DP_SEC_CNTL,\
-+ .DP_STEER_FIFO = mmDP ## id ## _DP_STEER_FIFO,\
-+ .DP_VID_M = mmDP ## id ## _DP_VID_M,\
-+ .DP_VID_N = mmDP ## id ## _DP_VID_N,\
-+ .DP_VID_STREAM_CNTL = mmDP ## id ## _DP_VID_STREAM_CNTL,\
-+ .DP_VID_TIMING = mmDP ## id ## _DP_VID_TIMING,\
-+ .HDMI_CONTROL = mmDIG ## id ## _HDMI_CONTROL,\
-+ .HDMI_GC = mmDIG ## id ## _HDMI_GC,\
-+ .HDMI_GENERIC_PACKET_CONTROL0 = mmDIG ## id ## _HDMI_GENERIC_PACKET_CONTROL0,\
-+ .HDMI_GENERIC_PACKET_CONTROL1 = mmDIG ## id ## _HDMI_GENERIC_PACKET_CONTROL1,\
-+ .HDMI_INFOFRAME_CONTROL0 = mmDIG ## id ## _HDMI_INFOFRAME_CONTROL0,\
-+ .HDMI_INFOFRAME_CONTROL1 = mmDIG ## id ## _HDMI_INFOFRAME_CONTROL1,\
-+ .HDMI_VBI_PACKET_CONTROL = mmDIG ## id ## _HDMI_VBI_PACKET_CONTROL,\
-+ .TMDS_CNTL = mmDIG ## id ## _TMDS_CNTL\
-+}
-+
-+static const struct dce110_stream_enc_registers stream_enc_regs[] = {
-+ stream_enc_regs(0),
-+ stream_enc_regs(1),
-+ stream_enc_regs(2),
-+ stream_enc_regs(3),
-+ stream_enc_regs(4),
-+ stream_enc_regs(5)
-+};
-+
-+static const struct dce110_clk_src_reg_offsets dce80_clk_src_reg_offsets[] = {
-+ {
-+ .pll_cntl = mmDCCG_PLL0_PLL_CNTL,
-+ .pixclk_resync_cntl = mmPIXCLK0_RESYNC_CNTL
-+ },
-+ {
-+ .pll_cntl = mmDCCG_PLL1_PLL_CNTL,
-+ .pixclk_resync_cntl = mmPIXCLK1_RESYNC_CNTL
-+ },
-+ {
-+ .pll_cntl = mmDCCG_PLL2_PLL_CNTL,
-+ .pixclk_resync_cntl = mmPIXCLK2_RESYNC_CNTL
-+ }
-+};
-+
-+static struct timing_generator *dce80_timing_generator_create(
-+ struct adapter_service *as,
-+ struct dc_context *ctx,
-+ uint32_t instance,
-+ const struct dce110_timing_generator_offsets *offsets)
-+{
-+ struct dce110_timing_generator *tg110 =
-+ dm_alloc(ctx, sizeof(struct dce110_timing_generator));
-+
-+ if (!tg110)
-+ return NULL;
-+
-+ if (dce80_timing_generator_construct(tg110, as, ctx, instance, offsets))
-+ return &tg110->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(ctx, tg110);
-+ return NULL;
-+}
-+
-+static struct stream_encoder *dce80_stream_encoder_create(
-+ enum engine_id eng_id,
-+ struct dc_context *ctx,
-+ struct dc_bios *dcb,
-+ const struct dce110_stream_enc_registers *regs)
-+{
-+ struct dce110_stream_encoder *enc110 =
-+ dm_alloc(ctx, sizeof(struct dce110_stream_encoder));
-+
-+ if (!enc110)
-+ return NULL;
-+
-+ if (dce80_stream_encoder_construct(enc110, ctx, dcb, eng_id, regs))
-+ return &enc110->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(ctx, enc110);
-+ return NULL;
-+}
-+
-+
-+static struct mem_input *dce80_mem_input_create(
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_mem_input_reg_offsets *offsets)
-+{
-+ struct dce110_mem_input *mem_input80 =
-+ dm_alloc(ctx, sizeof(struct dce110_mem_input));
-+
-+ if (!mem_input80)
-+ return NULL;
-+
-+ if (dce80_mem_input_construct(mem_input80,
-+ ctx, inst, offsets))
-+ return &mem_input80->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(ctx, mem_input80);
-+ return NULL;
-+}
-+
-+static void dce80_transform_destroy(struct transform **xfm)
-+{
-+ dm_free((*xfm)->ctx, TO_DCE80_TRANSFORM(*xfm));
-+ *xfm = NULL;
-+}
-+
-+static struct transform *dce80_transform_create(
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce80_transform_reg_offsets *offsets)
-+{
-+ struct dce80_transform *transform =
-+ dm_alloc(ctx, sizeof(struct dce80_transform));
-+
-+ if (!transform)
-+ return NULL;
-+
-+ if (dce80_transform_construct(transform, ctx, inst, offsets))
-+ return &transform->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(ctx, transform);
-+ return NULL;
-+}
-+
-+static struct input_pixel_processor *dce80_ipp_create(
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_ipp_reg_offsets *offset)
-+{
-+ struct dce110_ipp *ipp =
-+ dm_alloc(ctx, sizeof(struct dce110_ipp));
-+
-+ if (!ipp)
-+ return NULL;
-+
-+ if (dce80_ipp_construct(ipp, ctx, inst, offset))
-+ return &ipp->base;
-+
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(ctx, ipp);
-+ return NULL;
-+}
-+
-+struct link_encoder *dce80_link_encoder_create(
-+ const struct encoder_init_data *enc_init_data)
-+{
-+ struct dce110_link_encoder *enc110 =
-+ dm_alloc(
-+ enc_init_data->ctx,
-+ sizeof(struct dce110_link_encoder));
-+
-+ if (!enc110)
-+ return NULL;
-+
-+ if (dce80_link_encoder_construct(
-+ enc110,
-+ enc_init_data,
-+ &link_enc_regs[enc_init_data->transmitter],
-+ &link_enc_aux_regs[enc_init_data->channel - 1],
-+ &link_enc_bl_regs))
-+ return &enc110->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(enc_init_data->ctx, enc110);
-+ return NULL;
-+}
-+
-+struct clock_source *dce80_clock_source_create(
-+ struct dc_context *ctx,
-+ struct dc_bios *bios,
-+ enum clock_source_id id,
-+ const struct dce110_clk_src_reg_offsets *offsets)
-+{
-+ struct dce110_clk_src *clk_src =
-+ dm_alloc(ctx, sizeof(struct dce110_clk_src));
-+
-+ if (!clk_src)
-+ return NULL;
-+
-+ if (dce110_clk_src_construct(clk_src, ctx, bios, id, offsets))
-+ return &clk_src->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+}
-+
-+void dce80_clock_source_destroy(struct clock_source **clk_src)
-+{
-+ dm_free((*clk_src)->ctx, TO_DCE110_CLK_SRC(*clk_src));
-+ *clk_src = NULL;
-+}
-+
-+void dce80_destruct_resource_pool(struct resource_pool *pool)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < pool->pipe_count; i++) {
-+ if (pool->opps[i] != NULL)
-+ dce80_opp_destroy(&pool->opps[i]);
-+
-+ if (pool->transforms[i] != NULL)
-+ dce80_transform_destroy(&pool->transforms[i]);
-+
-+ if (pool->ipps[i] != NULL)
-+ dce80_ipp_destroy(&pool->ipps[i]);
-+
-+ if (pool->mis[i] != NULL) {
-+ dm_free(pool->mis[i]->ctx,
-+ TO_DCE110_MEM_INPUT(pool->mis[i]));
-+ pool->mis[i] = NULL;
-+ }
-+
-+ if (pool->timing_generators[i] != NULL) {
-+ dm_free(pool->timing_generators[i]->ctx, DCE110TG_FROM_TG(pool->timing_generators[i]));
-+ pool->timing_generators[i] = NULL;
-+ }
-+ }
-+
-+ for (i = 0; i < pool->stream_enc_count; i++) {
-+ if (pool->stream_enc[i] != NULL)
-+ dm_free(pool->stream_enc[i]->ctx,
-+ DCE110STRENC_FROM_STRENC(pool->stream_enc[i]));
-+ }
-+
-+ for (i = 0; i < pool->clk_src_count; i++) {
-+ if (pool->clock_sources[i] != NULL) {
-+ dce80_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 struct clock_source *find_first_free_pll(
-+ struct resource_context *res_ctx)
-+{
-+ if (res_ctx->clock_source_ref_count[DCE80_CLK_SRC_PLL0] == 0) {
-+ return res_ctx->pool.clock_sources[DCE80_CLK_SRC_PLL0];
-+ }
-+ if (res_ctx->clock_source_ref_count[DCE80_CLK_SRC_PLL1] == 0) {
-+ return res_ctx->pool.clock_sources[DCE80_CLK_SRC_PLL1];
-+ }
-+ if (res_ctx->clock_source_ref_count[DCE80_CLK_SRC_PLL2] == 0) {
-+ return res_ctx->pool.clock_sources[DCE80_CLK_SRC_PLL2];
-+ }
-+
-+ return 0;
-+}
-+
-+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 pipe_ctx *pipe_ctx,
-+ struct audio_output *audio_output)
-+{
-+ const struct core_stream *stream = pipe_ctx->stream;
-+ audio_output->engine_id = pipe_ctx->stream_enc->id;
-+
-+ audio_output->signal = pipe_ctx->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 =
-+ pipe_ctx->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 =
-+ pipe_ctx->pix_clk_params.requested_pix_clk;
-+
-+ if (pipe_ctx->signal == SIGNAL_TYPE_DISPLAY_PORT ||
-+ pipe_ctx->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
-+ audio_output->pll_info.dp_dto_source_clock_in_khz =
-+ dal_display_clock_get_dp_ref_clk_frequency(
-+ pipe_ctx->dis_clk);
-+ }
-+
-+ audio_output->pll_info.feed_back_divider =
-+ pipe_ctx->pll_settings.feedback_divider;
-+
-+ audio_output->pll_info.dto_source =
-+ translate_to_dto_source(
-+ pipe_ctx->pipe_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 =
-+ pipe_ctx->pll_settings.ss_percentage;
-+}
-+
-+static void get_pixel_clock_parameters(
-+ const struct pipe_ctx *pipe_ctx,
-+ struct pixel_clk_params *pixel_clk_params)
-+{
-+ const struct core_stream *stream = pipe_ctx->stream;
-+ 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 = pipe_ctx->pipe_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_pipe_hw_param(struct pipe_ctx *pipe_ctx)
-+{
-+ /*TODO: unhardcode*/
-+ pipe_ctx->max_tmds_clk_from_edid_in_mhz = 0;
-+ pipe_ctx->max_hdmi_deep_color = COLOR_DEPTH_121212;
-+ pipe_ctx->max_hdmi_pixel_clock = 600000;
-+
-+ get_pixel_clock_parameters(pipe_ctx, &pipe_ctx->pix_clk_params);
-+ pipe_ctx->clock_source->funcs->get_pix_clk_dividers(
-+ pipe_ctx->clock_source,
-+ &pipe_ctx->pix_clk_params,
-+ &pipe_ctx->pll_settings);
-+
-+ build_audio_output(pipe_ctx, &pipe_ctx->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, 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->public.stream_count; j++) {
-+ struct core_stream *stream =
-+ DC_STREAM_TO_CORE(target->public.streams[j]);
-+ struct core_link *link = stream->sink->link;
-+
-+ for (k = 0; k < MAX_PIPES; k++) {
-+ struct pipe_ctx *pipe_ctx =
-+ &context->res_ctx.pipe_ctx[k];
-+
-+ if (context->res_ctx.pipe_ctx[k].stream != stream)
-+ continue;
-+
-+ if (!pipe_ctx->tg->funcs->validate_timing(
-+ pipe_ctx->tg, &stream->public.timing))
-+ return DC_FAIL_CONTROLLER_VALIDATE;
-+
-+ status = build_pipe_hw_param(pipe_ctx);
-+
-+ if (status != DC_OK)
-+ return status;
-+
-+ if (!link->link_enc->funcs->validate_output_with_stream(
-+ link->link_enc,
-+ pipe_ctx))
-+ 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(pipe_ctx);
-+
-+ /* do not need to validate non root pipes */
-+ break;
-+ }
-+ }
-+ }
-+
-+ return DC_OK;
-+}
-+
-+enum dc_status dce80_validate_bandwidth(
-+ const struct dc *dc,
-+ struct validate_context *context)
-+{
-+ uint8_t i;
-+ enum dc_status result = DC_ERROR_UNEXPECTED;
-+ uint8_t number_of_displays = 0;
-+ uint8_t max_htaps = 1;
-+ uint8_t max_vtaps = 1;
-+ bool all_displays_in_sync = true;
-+ struct dc_crtc_timing prev_timing;
-+
-+ memset(&context->bw_mode_data, 0, sizeof(context->bw_mode_data));
-+
-+ for (i = 0; i < MAX_PIPES; i++) {
-+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
-+ struct bw_calcs_input_single_display *disp = &context->
-+ bw_mode_data.displays_data[number_of_displays];
-+
-+ if (pipe_ctx->stream == NULL)
-+ continue;
-+
-+ if (pipe_ctx->ratios.vert.value == 0) {
-+ disp->graphics_scale_ratio = bw_int_to_fixed(1);
-+ disp->graphics_h_taps = 2;
-+ disp->graphics_v_taps = 2;
-+
-+ /* TODO: remove when bw formula accepts taps per
-+ * display
-+ */
-+ if (max_vtaps < 2)
-+ max_vtaps = 2;
-+ if (max_htaps < 2)
-+ max_htaps = 2;
-+
-+ } else {
-+ disp->graphics_scale_ratio =
-+ fixed31_32_to_bw_fixed(
-+ pipe_ctx->ratios.vert.value);
-+ disp->graphics_h_taps = pipe_ctx->taps.h_taps;
-+ disp->graphics_v_taps = pipe_ctx->taps.v_taps;
-+
-+ /* TODO: remove when bw formula accepts taps per
-+ * display
-+ */
-+ if (max_vtaps < pipe_ctx->taps.v_taps)
-+ max_vtaps = pipe_ctx->taps.v_taps;
-+ if (max_htaps < pipe_ctx->taps.h_taps)
-+ max_htaps = pipe_ctx->taps.h_taps;
-+ }
-+
-+ disp->graphics_src_width =
-+ pipe_ctx->stream->public.timing.h_addressable;
-+ disp->graphics_src_height =
-+ pipe_ctx->stream->public.timing.v_addressable;
-+ disp->h_total = pipe_ctx->stream->public.timing.h_total;
-+ disp->pixel_rate = bw_frc_to_fixed(
-+ pipe_ctx->stream->public.timing.pix_clk_khz, 1000);
-+
-+ /*TODO: get from surface*/
-+ disp->graphics_bytes_per_pixel = 4;
-+ disp->graphics_tiling_mode = bw_def_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 = bw_def_mono;
-+ disp->underlay_mode = bw_def_none;
-+
-+ /*All displays will be synchronized if timings are all
-+ * the same
-+ */
-+ if (number_of_displays != 0 && all_displays_in_sync)
-+ if (dm_memcmp(&prev_timing,
-+ &pipe_ctx->stream->public.timing,
-+ sizeof(struct dc_crtc_timing)) != 0)
-+ all_displays_in_sync = false;
-+ if (number_of_displays == 0)
-+ prev_timing = pipe_ctx->stream->public.timing;
-+
-+ number_of_displays++;
-+ }
-+
-+ /* TODO: remove when bw formula accepts taps per
-+ * display
-+ */
-+ context->bw_mode_data.displays_data[0].graphics_v_taps = max_vtaps;
-+ context->bw_mode_data.displays_data[0].graphics_h_taps = max_htaps;
-+
-+ context->bw_mode_data.number_of_displays = number_of_displays;
-+ context->bw_mode_data.display_synchronization_enabled =
-+ all_displays_in_sync;
-+
-+ dal_logger_write(
-+ dc->ctx->logger,
-+ LOG_MAJOR_BWM,
-+ LOG_MINOR_BWM_REQUIRED_BANDWIDTH_CALCS,
-+ "%s: start",
-+ __func__);
-+
-+ if (!bw_calcs(
-+ dc->ctx,
-+ &dc->bw_dceip,
-+ &dc->bw_vbios,
-+ &context->bw_mode_data,
-+ &context->bw_results))
-+ result = DC_FAIL_BANDWIDTH_VALIDATE;
-+ else
-+ result = DC_OK;
-+
-+ if (result == DC_FAIL_BANDWIDTH_VALIDATE)
-+ dal_logger_write(dc->ctx->logger,
-+ LOG_MAJOR_BWM,
-+ LOG_MINOR_BWM_MODE_VALIDATION,
-+ "%s: Bandwidth validation failed!",
-+ __func__);
-+
-+ if (dm_memcmp(&dc->current_context.bw_results,
-+ &context->bw_results, sizeof(context->bw_results))) {
-+ struct log_entry log_entry;
-+ dal_logger_open(
-+ dc->ctx->logger,
-+ &log_entry,
-+ LOG_MAJOR_BWM,
-+ LOG_MINOR_BWM_REQUIRED_BANDWIDTH_CALCS);
-+ dal_logger_append(&log_entry, "%s: finish, numDisplays: %d\n"
-+ "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
-+ "stutMark_b: %d stutMark_a: %d\n",
-+ __func__, number_of_displays,
-+ context->bw_results.nbp_state_change_wm_ns[0].b_mark,
-+ context->bw_results.nbp_state_change_wm_ns[0].a_mark,
-+ context->bw_results.urgent_wm_ns[0].b_mark,
-+ context->bw_results.urgent_wm_ns[0].a_mark,
-+ context->bw_results.stutter_exit_wm_ns[0].b_mark,
-+ context->bw_results.stutter_exit_wm_ns[0].a_mark);
-+ dal_logger_append(&log_entry,
-+ "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
-+ "stutMark_b: %d stutMark_a: %d\n",
-+ context->bw_results.nbp_state_change_wm_ns[1].b_mark,
-+ context->bw_results.nbp_state_change_wm_ns[1].a_mark,
-+ context->bw_results.urgent_wm_ns[1].b_mark,
-+ context->bw_results.urgent_wm_ns[1].a_mark,
-+ context->bw_results.stutter_exit_wm_ns[1].b_mark,
-+ context->bw_results.stutter_exit_wm_ns[1].a_mark);
-+ dal_logger_append(&log_entry,
-+ "nbpMark_b: %d nbpMark_a: %d urgentMark_b: %d urgentMark_a: %d\n"
-+ "stutMark_b: %d stutMark_a: %d stutter_mode_enable: %d\n",
-+ context->bw_results.nbp_state_change_wm_ns[2].b_mark,
-+ context->bw_results.nbp_state_change_wm_ns[2].a_mark,
-+ context->bw_results.urgent_wm_ns[2].b_mark,
-+ context->bw_results.urgent_wm_ns[2].a_mark,
-+ context->bw_results.stutter_exit_wm_ns[2].b_mark,
-+ context->bw_results.stutter_exit_wm_ns[2].a_mark,
-+ context->bw_results.stutter_mode_enable);
-+ dal_logger_append(&log_entry,
-+ "cstate: %d pstate: %d nbpstate: %d sync: %d dispclk: %d\n"
-+ "sclk: %d sclk_sleep: %d yclk: %d blackout_duration: %d\n",
-+ context->bw_results.cpuc_state_change_enable,
-+ context->bw_results.cpup_state_change_enable,
-+ context->bw_results.nbp_state_change_enable,
-+ context->bw_results.all_displays_in_sync,
-+ context->bw_results.dispclk_khz,
-+ context->bw_results.required_sclk,
-+ context->bw_results.required_sclk_deep_sleep,
-+ context->bw_results.required_yclk,
-+ context->bw_results.required_blackout_duration_us);
-+ dal_logger_close(&log_entry);
-+ }
-+ return result;
-+}
-+
-+static void set_target_unchanged(
-+ struct validate_context *context,
-+ uint8_t target_idx)
-+{
-+ uint8_t i, j;
-+ struct core_target *target = context->targets[target_idx];
-+ context->target_flags[target_idx].unchanged = true;
-+ for (i = 0; i < target->public.stream_count; i++) {
-+ struct core_stream *stream =
-+ DC_STREAM_TO_CORE(target->public.streams[i]);
-+ for (j = 0; j < MAX_PIPES; j++) {
-+ if (context->res_ctx.pipe_ctx[j].stream == stream)
-+ context->res_ctx.pipe_ctx[j].flags.unchanged =
-+ true;
-+ }
-+ }
-+}
-+
-+static enum dc_status map_clock_resources(
-+ const struct dc *dc,
-+ struct validate_context *context)
-+{
-+ uint8_t i, j, k;
-+
-+ /* 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->public.stream_count; j++) {
-+ struct core_stream *stream =
-+ DC_STREAM_TO_CORE(target->public.streams[j]);
-+
-+ for (k = 0; k < MAX_PIPES; k++) {
-+ struct pipe_ctx *pipe_ctx =
-+ &context->res_ctx.pipe_ctx[k];
-+
-+ if (context->res_ctx.pipe_ctx[k].stream != stream)
-+ continue;
-+
-+ if (dc_is_dp_signal(pipe_ctx->signal)
-+ || pipe_ctx->signal == SIGNAL_TYPE_VIRTUAL)
-+ pipe_ctx->clock_source = context->res_ctx.
-+ pool.clock_sources[DCE80_CLK_SRC_EXT];
-+ else
-+ pipe_ctx->clock_source =
-+ find_used_clk_src_for_sharing(
-+ &context->res_ctx, pipe_ctx);
-+ if (pipe_ctx->clock_source == NULL)
-+ pipe_ctx->clock_source =
-+ find_first_free_pll(&context->res_ctx);
-+
-+ if (pipe_ctx->clock_source == NULL)
-+ return DC_NO_CLOCK_SOURCE_RESOURCE;
-+
-+ reference_clock_source(
-+ &context->res_ctx,
-+ pipe_ctx->clock_source);
-+
-+ /* only one cs per stream regardless of mpo */
-+ break;
-+ }
-+ }
-+ }
-+
-+ return DC_OK;
-+}
-+
-+enum dc_status dce80_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++) {
-+ bool unchanged = false;
-+
-+ context->targets[i] = DC_TARGET_TO_CORE(set[i].target);
-+ context->target_count++;
-+
-+ for (j = 0; j < dc->current_context.target_count; j++)
-+ if (dc->current_context.targets[j]
-+ == context->targets[i]) {
-+ unchanged = true;
-+ set_target_unchanged(context, i);
-+ context->target_status[i] =
-+ dc->current_context.target_status[j];
-+ }
-+ if (!unchanged)
-+ if (!attach_surfaces_to_context(
-+ (struct dc_surface **)set[i].surfaces,
-+ set[i].surface_count,
-+ &context->targets[i]->public,
-+ context)) {
-+ DC_ERROR("Failed to attach surface to target!\n");
-+ return DC_FAIL_ATTACH_SURFACES;
-+ }
-+ }
-+
-+ context->res_ctx.pool = dc->res_pool;
-+
-+ result = map_resources(dc, context);
-+
-+ if (result == DC_OK)
-+ result = map_clock_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 = dce80_validate_bandwidth(dc, context);
-+
-+ return result;
-+}
-+
-+static struct resource_funcs dce80_res_pool_funcs = {
-+ .destruct = dce80_destruct_resource_pool,
-+ .link_enc_create = dce80_link_encoder_create,
-+ .link_enc_destroy = dce110_link_encoder_destroy,
-+ .validate_with_context = dce80_validate_with_context,
-+ .validate_bandwidth = dce80_validate_bandwidth
-+};
-+
-+bool dce80_construct_resource_pool(
-+ struct adapter_service *adapter_serv,
-+ uint8_t num_virtual_links,
-+ struct dc *dc,
-+ struct resource_pool *pool)
-+{
-+ unsigned int i;
-+ struct audio_init_data audio_init_data = { 0 };
-+ struct dc_context *ctx = dc->ctx;
-+ pool->adapter_srv = adapter_serv;
-+ pool->funcs = &dce80_res_pool_funcs;
-+
-+ pool->stream_engines.engine.ENGINE_ID_DIGA = 1;
-+ pool->stream_engines.engine.ENGINE_ID_DIGB = 1;
-+ pool->stream_engines.engine.ENGINE_ID_DIGC = 1;
-+ pool->stream_engines.engine.ENGINE_ID_DIGD = 1;
-+ pool->stream_engines.engine.ENGINE_ID_DIGE = 1;
-+ pool->stream_engines.engine.ENGINE_ID_DIGF = 1;
-+
-+ pool->clock_sources[DCE80_CLK_SRC_PLL0] = dce80_clock_source_create(
-+ ctx, dal_adapter_service_get_bios_parser(adapter_serv),
-+ CLOCK_SOURCE_ID_PLL0, &dce80_clk_src_reg_offsets[0]);
-+ pool->clock_sources[DCE80_CLK_SRC_PLL1] = dce80_clock_source_create(
-+ ctx, dal_adapter_service_get_bios_parser(adapter_serv),
-+ CLOCK_SOURCE_ID_PLL1, &dce80_clk_src_reg_offsets[1]);
-+ pool->clock_sources[DCE80_CLK_SRC_PLL2] = dce80_clock_source_create(
-+ ctx, dal_adapter_service_get_bios_parser(adapter_serv),
-+ CLOCK_SOURCE_ID_PLL2, &dce80_clk_src_reg_offsets[2]);
-+ pool->clock_sources[DCE80_CLK_SRC_EXT] = dce80_clock_source_create(
-+ ctx, dal_adapter_service_get_bios_parser(adapter_serv),
-+ CLOCK_SOURCE_ID_EXTERNAL, &dce80_clk_src_reg_offsets[0]);
-+ pool->clk_src_count = DCE80_CLK_SRC_TOTAL;
-+
-+ for (i = 0; i < pool->clk_src_count; i++) {
-+ if (pool->clock_sources[i] == NULL) {
-+ dm_error("DC: failed to create clock sources!\n");
-+ BREAK_TO_DEBUGGER();
-+ goto clk_src_create_fail;
-+ }
-+ }
-+
-+ pool->display_clock = dal_display_clock_dce80_create(ctx, adapter_serv);
-+ if (pool->display_clock == NULL) {
-+ dm_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->pipe_count =
-+ dal_adapter_service_get_func_controllers_num(adapter_serv);
-+ pool->stream_enc_count =
-+ dal_adapter_service_get_stream_engines_num(adapter_serv);
-+ pool->scaler_filter = dal_scaler_filter_create(ctx);
-+ if (pool->scaler_filter == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dm_error("DC: failed to create filter!\n");
-+ goto filter_create_fail;
-+ }
-+
-+ for (i = 0; i < pool->pipe_count; i++) {
-+ pool->timing_generators[i] = dce80_timing_generator_create(
-+ adapter_serv, ctx, i, &dce80_tg_offsets[i]);
-+ if (pool->timing_generators[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dm_error("DC: failed to create tg!\n");
-+ goto controller_create_fail;
-+ }
-+
-+ pool->mis[i] = dce80_mem_input_create(ctx, i,
-+ &dce80_mi_reg_offsets[i]);
-+ if (pool->mis[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dm_error("DC: failed to create memory input!\n");
-+ goto controller_create_fail;
-+ }
-+
-+ pool->ipps[i] = dce80_ipp_create(ctx, i, &ipp_reg_offsets[i]);
-+ if (pool->ipps[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dm_error("DC: failed to create input pixel processor!\n");
-+ goto controller_create_fail;
-+ }
-+
-+ pool->transforms[i] = dce80_transform_create(
-+ ctx, i, &dce80_xfm_offsets[i]);
-+ if (pool->transforms[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dm_error("DC: failed to create transform!\n");
-+ goto controller_create_fail;
-+ }
-+ pool->transforms[i]->funcs->transform_set_scaler_filter(
-+ pool->transforms[i],
-+ pool->scaler_filter);
-+
-+ pool->opps[i] = dce80_opp_create(ctx, i);
-+ if (pool->opps[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dm_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->pipe_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();
-+ dm_error("DC: failed to create DPPs!\n");
-+ goto audio_create_fail;
-+ }
-+ pool->audio_count++;
-+ }
-+
-+ for (i = 0; i < pool->stream_enc_count; i++) {
-+ if (pool->stream_engines.u_all & 1 << i) {
-+ pool->stream_enc[i] = dce80_stream_encoder_create(
-+ i, dc->ctx,
-+ dal_adapter_service_get_bios_parser(
-+ adapter_serv),
-+ &stream_enc_regs[i]);
-+
-+ if (pool->stream_enc[i] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dm_error("DC: failed to create stream_encoder!\n");
-+ goto stream_enc_create_fail;
-+ }
-+ }
-+ }
-+
-+ for (i = 0; i < num_virtual_links; i++) {
-+ pool->stream_enc[pool->stream_enc_count] =
-+ virtual_stream_encoder_create(
-+ dc->ctx, dal_adapter_service_get_bios_parser(
-+ adapter_serv));
-+ if (pool->stream_enc[pool->stream_enc_count] == NULL) {
-+ BREAK_TO_DEBUGGER();
-+ dm_error("DC: failed to create stream_encoder!\n");
-+ goto stream_enc_create_fail;
-+ }
-+ pool->stream_enc_count++;
-+ }
-+
-+ return true;
-+
-+stream_enc_create_fail:
-+ for (i = 0; i < pool->stream_enc_count; i++) {
-+ if (pool->stream_enc[i] != NULL)
-+ dm_free(pool->stream_enc[i]->ctx,
-+ DCE110STRENC_FROM_STRENC(pool->stream_enc[i]));
-+ }
-+
-+audio_create_fail:
-+ for (i = 0; i < pool->pipe_count; i++) {
-+ if (pool->audios[i] != NULL)
-+ dal_audio_destroy(&pool->audios[i]);
-+ }
-+
-+controller_create_fail:
-+ for (i = 0; i < pool->pipe_count; i++) {
-+ if (pool->opps[i] != NULL)
-+ dce80_opp_destroy(&pool->opps[i]);
-+
-+ if (pool->transforms[i] != NULL)
-+ dce80_transform_destroy(&pool->transforms[i]);
-+
-+ if (pool->ipps[i] != NULL)
-+ dce80_ipp_destroy(&pool->ipps[i]);
-+
-+ if (pool->mis[i] != NULL) {
-+ dm_free(pool->mis[i]->ctx,
-+ TO_DCE110_MEM_INPUT(pool->mis[i]));
-+ pool->mis[i] = NULL;
-+ }
-+ if (pool->timing_generators[i] != NULL) {
-+ dm_free(pool->timing_generators[i]->ctx,
-+ DCE110TG_FROM_TG(pool->timing_generators[i]));
-+ pool->timing_generators[i] = NULL;
-+ }
-+ }
-+
-+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)
-+ dce80_clock_source_destroy(&pool->clock_sources[i]);
-+ }
-+
-+ return false;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.h b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.h
-new file mode 100644
-index 0000000..3d0f8fe
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_resource.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 __DC_RESOURCE_DCE80_H__
-+#define __DC_RESOURCE_DCE80_H__
-+
-+#include "core_types.h"
-+
-+struct adapter_service;
-+struct dc;
-+struct resource_pool;
-+
-+bool dce80_construct_resource_pool(
-+ struct adapter_service *adapter_serv,
-+ uint8_t num_virtual_links,
-+ struct dc *dc,
-+ struct resource_pool *pool);
-+
-+#endif /* __DC_RESOURCE_DCE80_H__ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_stream_encoder.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_stream_encoder.c
-new file mode 100644
-index 0000000..d45a1e4
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_stream_encoder.c
-@@ -0,0 +1,1104 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+#include "bios_parser_types.h"
-+#include "dc_bios_types.h"
-+#include "../dce110/dce110_stream_encoder.h"
-+#include "dce80_stream_encoder.h"
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+#define LINK_REG(reg)\
-+ (enc110->regs->reg)
-+
-+#define VBI_LINE_0 0
-+#define DP_BLANK_MAX_RETRY 20
-+
-+enum dp_pixel_encoding {
-+ DP_PIXEL_ENCODING_RGB444 = 0,
-+ DP_PIXEL_ENCODING_YCBCR422,
-+ DP_PIXEL_ENCODING_YCBCR444,
-+ DP_PIXEL_ENCODING_RGB_WIDE_GAMUT,
-+ DP_PIXEL_ENCODING_Y_ONLY
-+};
-+
-+enum dp_component_depth {
-+ DP_COMPONENT_DEPTH_6BPC = 0,
-+ DP_COMPONENT_DEPTH_8BPC,
-+ DP_COMPONENT_DEPTH_10BPC,
-+ DP_COMPONENT_DEPTH_12BPC
-+};
-+
-+enum {
-+ DP_MST_UPDATE_MAX_RETRY = 50
-+};
-+
-+static struct stream_encoder_funcs dce80_str_enc_funcs = {
-+ .dp_set_stream_attribute =
-+ dce80_stream_encoder_dp_set_stream_attribute,
-+ .hdmi_set_stream_attribute =
-+ dce80_stream_encoder_hdmi_set_stream_attribute,
-+ .dvi_set_stream_attribute =
-+ dce80_stream_encoder_dvi_set_stream_attribute,
-+ .set_mst_bandwidth =
-+ dce80_stream_encoder_set_mst_bandwidth,
-+ .update_hdmi_info_packets =
-+ dce80_stream_encoder_update_hdmi_info_packets,
-+ .stop_hdmi_info_packets =
-+ dce80_stream_encoder_stop_hdmi_info_packets,
-+ .update_dp_info_packets =
-+ dce80_stream_encoder_update_dp_info_packets,
-+ .stop_dp_info_packets =
-+ dce80_stream_encoder_stop_dp_info_packets,
-+ .dp_blank =
-+ dce80_stream_encoder_dp_blank,
-+ .dp_unblank =
-+ dce80_stream_encoder_dp_unblank,
-+};
-+
-+static void dce80_update_generic_info_packet(
-+ struct dce110_stream_encoder *enc110,
-+ uint32_t packet_index,
-+ const struct encoder_info_packet *info_packet)
-+{
-+ struct dc_context *ctx = enc110->base.ctx;
-+ uint32_t addr;
-+ uint32_t regval;
-+ /* choose which generic packet to use */
-+ {
-+ addr = LINK_REG(AFMT_VBI_PACKET_CONTROL);
-+
-+ regval = dm_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ regval,
-+ packet_index,
-+ AFMT_VBI_PACKET_CONTROL,
-+ AFMT_GENERIC_INDEX);
-+
-+ dm_write_reg(ctx, addr, regval);
-+ }
-+
-+ /* write generic packet header
-+ * (4th byte is for GENERIC0 only)
-+ */
-+ {
-+ addr = LINK_REG(AFMT_GENERIC_HDR);
-+
-+ 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);
-+
-+ dm_write_reg(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 = LINK_REG(AFMT_GENERIC_0);
-+
-+ do {
-+ dm_write_reg(ctx, addr++, *content++);
-+
-+ ++counter;
-+ } while (counter < 7);
-+ }
-+
-+ addr = LINK_REG(AFMT_GENERIC_7);
-+
-+ dm_write_reg(
-+ ctx,
-+ addr,
-+ 0);
-+
-+ /* force double-buffered packet update */
-+ {
-+ addr = LINK_REG(AFMT_VBI_PACKET_CONTROL);
-+
-+ regval = dm_read_reg(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);
-+
-+ dm_write_reg(ctx, addr, regval);
-+ }
-+}
-+
-+static void dce80_update_hdmi_info_packet(
-+ struct dce110_stream_encoder *enc110,
-+ uint32_t packet_index,
-+ const struct encoder_info_packet *info_packet)
-+{
-+ struct dc_context *ctx = enc110->base.ctx;
-+ uint32_t cont, send, line;
-+ uint32_t addr = 0;
-+ uint32_t regval;
-+
-+ if (info_packet->valid) {
-+ dce80_update_generic_info_packet(
-+ enc110,
-+ 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 = LINK_REG(HDMI_GENERIC_PACKET_CONTROL0);
-+ break;
-+ case 2:
-+ case 3:
-+ addr = LINK_REG(HDMI_GENERIC_PACKET_CONTROL1);
-+ break;
-+ default:
-+ /* invalid HW packet index */
-+ dal_logger_write(
-+ ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_ENCODER,
-+ "Invalid HW packet index: %s()\n",
-+ __func__);
-+ break;
-+ }
-+
-+ regval = dm_read_reg(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(
-+ ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_ENCODER,
-+ "Invalid HW packet index: %s()\n",
-+ __func__);
-+ break;
-+ }
-+
-+ dm_write_reg(ctx, addr, regval);
-+}
-+
-+bool dce80_stream_encoder_construct(
-+ struct dce110_stream_encoder *enc110,
-+ struct dc_context *ctx,
-+ struct dc_bios *dcb,
-+ enum engine_id eng_id,
-+ const struct dce110_stream_enc_registers *regs)
-+{
-+ if (!enc110)
-+ return false;
-+ if (!dcb)
-+ return false;
-+
-+ enc110->base.funcs = &dce80_str_enc_funcs;
-+ enc110->base.ctx = ctx;
-+ enc110->base.id = eng_id;
-+ enc110->base.bp = dcb;
-+ enc110->regs = regs;
-+
-+ return true;
-+}
-+
-+/* setup stream encoder in dp mode */
-+void dce80_stream_encoder_dp_set_stream_attribute(
-+ struct stream_encoder *enc,
-+ struct dc_crtc_timing *crtc_timing)
-+{
-+ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
-+ struct dc_context *ctx = enc110->base.ctx;
-+ uint32_t addr = LINK_REG(DP_PIXEL_FORMAT);
-+ uint32_t value = dm_read_reg(ctx, addr);
-+
-+ /* set pixel encoding */
-+ switch (crtc_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 (crtc_timing->flags.Y_ONLY)
-+ if (crtc_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 (crtc_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);
-+
-+ dm_write_reg(ctx, addr, value);
-+
-+}
-+
-+/* setup stream encoder in hdmi mode */
-+void dce80_stream_encoder_hdmi_set_stream_attribute(
-+ struct stream_encoder *enc,
-+ struct dc_crtc_timing *crtc_timing,
-+ bool enable_audio)
-+{
-+ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
-+ struct dc_context *ctx = enc110->base.ctx;
-+ uint32_t addr = LINK_REG(TMDS_CNTL);
-+ uint32_t value = dm_read_reg(ctx, addr);
-+ uint32_t output_pixel_clock = crtc_timing->pix_clk_khz;
-+ struct bp_encoder_control cntl = {0};
-+
-+ cntl.action = ENCODER_CONTROL_SETUP;
-+ cntl.engine_id = enc110->base.id;
-+ cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A;
-+ cntl.enable_dp_audio = enable_audio;
-+ cntl.pixel_clock = crtc_timing->pix_clk_khz;
-+ cntl.lanes_number = LANE_COUNT_FOUR;
-+ cntl.color_depth = crtc_timing->display_color_depth;
-+
-+ if (enc110->base.bp->funcs->encoder_control(
-+ enc110->base.bp, &cntl) != BP_RESULT_OK)
-+ return;
-+
-+ switch (crtc_timing->pixel_encoding) {
-+ case PIXEL_ENCODING_YCBCR422:
-+ set_reg_field_value(value, 1, TMDS_CNTL, TMDS_PIXEL_ENCODING);
-+ break;
-+ default:
-+ set_reg_field_value(value, 0, TMDS_CNTL, TMDS_PIXEL_ENCODING);
-+ break;
-+ }
-+
-+ set_reg_field_value(value, 0, TMDS_CNTL, TMDS_COLOR_FORMAT);
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* setup HDMI engine */
-+ addr = LINK_REG(HDMI_CONTROL);
-+ value = dm_read_reg(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);
-+
-+ switch (crtc_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 = (crtc_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 = (crtc_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 = (crtc_timing->pix_clk_khz * 48) / 24;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ dm_write_reg(ctx, addr, value);
-+
-+ addr = LINK_REG(HDMI_VBI_PACKET_CONTROL);
-+ value = dm_read_reg(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);
-+
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* following belongs to audio */
-+ addr = LINK_REG(HDMI_INFOFRAME_CONTROL0);
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ HDMI_INFOFRAME_CONTROL0,
-+ HDMI_AUDIO_INFO_SEND);
-+ dm_write_reg(ctx, addr, value);
-+
-+ addr = LINK_REG(AFMT_INFOFRAME_CONTROL0);
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AFMT_INFOFRAME_CONTROL0,
-+ AFMT_AUDIO_INFO_UPDATE);
-+ dm_write_reg(ctx, addr, value);
-+
-+ addr = LINK_REG(HDMI_INFOFRAME_CONTROL1);
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ VBI_LINE_0 + 2,
-+ HDMI_INFOFRAME_CONTROL1,
-+ HDMI_AUDIO_INFO_LINE);
-+ dm_write_reg(ctx, addr, value);
-+
-+ addr = LINK_REG(HDMI_GC);
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(value, 0, HDMI_GC, HDMI_GC_AVMUTE);
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+/* setup stream encoder in dvi mode */
-+void dce80_stream_encoder_dvi_set_stream_attribute(
-+ struct stream_encoder *enc,
-+ struct dc_crtc_timing *crtc_timing,
-+ bool is_dual_link)
-+{
-+ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
-+ struct dc_context *ctx = enc110->base.ctx;
-+ uint32_t addr = LINK_REG(TMDS_CNTL);
-+ uint32_t value = dm_read_reg(ctx, addr);
-+ struct bp_encoder_control cntl = {0};
-+
-+ cntl.action = ENCODER_CONTROL_SETUP;
-+ cntl.engine_id = enc110->base.id;
-+ cntl.signal = is_dual_link ?
-+ SIGNAL_TYPE_DVI_DUAL_LINK :
-+ SIGNAL_TYPE_DVI_SINGLE_LINK;
-+ cntl.enable_dp_audio = false;
-+ cntl.pixel_clock = crtc_timing->pix_clk_khz;
-+ cntl.lanes_number = (is_dual_link) ?
-+ LANE_COUNT_EIGHT : LANE_COUNT_FOUR;
-+ cntl.color_depth = crtc_timing->display_color_depth;
-+
-+ if (enc110->base.bp->funcs->encoder_control(
-+ enc110->base.bp, &cntl) != BP_RESULT_OK)
-+ return;
-+
-+ switch (crtc_timing->pixel_encoding) {
-+ case PIXEL_ENCODING_YCBCR422:
-+ set_reg_field_value(value, 1, TMDS_CNTL, TMDS_PIXEL_ENCODING);
-+ break;
-+ default:
-+ set_reg_field_value(value, 0, TMDS_CNTL, TMDS_PIXEL_ENCODING);
-+ break;
-+ }
-+
-+ switch (crtc_timing->pixel_encoding) {
-+ case COLOR_DEPTH_101010:
-+ if (crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB)
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ TMDS_CNTL,
-+ TMDS_COLOR_FORMAT);
-+ else
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ TMDS_CNTL,
-+ TMDS_COLOR_FORMAT);
-+ break;
-+ default:
-+ set_reg_field_value(value, 0, TMDS_CNTL, TMDS_COLOR_FORMAT);
-+ break;
-+ }
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+void dce80_stream_encoder_set_mst_bandwidth(
-+ struct stream_encoder *enc,
-+ struct fixed31_32 avg_time_slots_per_mtp)
-+{
-+ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
-+ struct dc_context *ctx = enc110->base.ctx;
-+ uint32_t addr;
-+ uint32_t field;
-+ uint32_t value;
-+ uint32_t retries = 0;
-+ 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));
-+
-+ {
-+ addr = LINK_REG(DP_MSE_RATE_CNTL);
-+ value = dm_read_reg(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);
-+
-+ dm_write_reg(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) */
-+ {
-+ addr = LINK_REG(DP_MSE_RATE_UPDATE);
-+
-+ do {
-+ value = dm_read_reg(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;
-+
-+ dm_delay_in_microseconds(ctx, 10);
-+
-+ ++retries;
-+ } while (retries < DP_MST_UPDATE_MAX_RETRY);
-+ }
-+}
-+
-+void dce80_stream_encoder_update_hdmi_info_packets(
-+ struct stream_encoder *enc,
-+ const struct encoder_info_frame *info_frame)
-+{
-+ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
-+ struct dc_context *ctx = enc110->base.ctx;
-+ uint32_t addr;
-+ uint32_t regval;
-+ uint32_t control0val;
-+ uint32_t control1val;
-+
-+ if (info_frame->avi.valid) {
-+ const uint32_t *content =
-+ (const uint32_t *) &info_frame->avi.sb[0];
-+
-+ addr = LINK_REG(AFMT_AVI_INFO0);
-+ regval = content[0];
-+
-+ dm_write_reg(
-+ ctx,
-+ addr,
-+ regval);
-+
-+ addr = LINK_REG(AFMT_AVI_INFO1);
-+ regval = content[1];
-+
-+ dm_write_reg(
-+ ctx,
-+ addr,
-+ regval);
-+
-+ addr = LINK_REG(AFMT_AVI_INFO2);
-+ regval = content[2];
-+
-+ dm_write_reg(
-+ ctx,
-+ addr,
-+ regval);
-+
-+ addr = LINK_REG(AFMT_AVI_INFO3);
-+ regval = content[3];
-+
-+ /* move version to AVI_INFO3 */
-+ set_reg_field_value(
-+ regval,
-+ info_frame->avi.hb1,
-+ AFMT_AVI_INFO3,
-+ AFMT_AVI_INFO_VERSION);
-+
-+ dm_write_reg(
-+ ctx,
-+ addr,
-+ regval);
-+
-+ addr = LINK_REG(HDMI_INFOFRAME_CONTROL0);
-+ control0val = dm_read_reg(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);
-+
-+ dm_write_reg(ctx, addr, control0val);
-+
-+ addr = LINK_REG(HDMI_INFOFRAME_CONTROL1);
-+
-+ control1val = dm_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ control1val,
-+ VBI_LINE_0 + 2,
-+ HDMI_INFOFRAME_CONTROL1,
-+ HDMI_AVI_INFO_LINE);
-+
-+ dm_write_reg(ctx, addr, control1val);
-+ } else {
-+ addr = LINK_REG(HDMI_INFOFRAME_CONTROL0);
-+
-+ regval = dm_read_reg(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);
-+
-+ dm_write_reg(ctx, addr, regval);
-+ }
-+
-+ dce80_update_hdmi_info_packet(enc110, 0, &info_frame->vendor);
-+ dce80_update_hdmi_info_packet(enc110, 1, &info_frame->gamut);
-+ dce80_update_hdmi_info_packet(enc110, 2, &info_frame->spd);
-+}
-+
-+void dce80_stream_encoder_stop_hdmi_info_packets(
-+ struct stream_encoder *enc)
-+{
-+ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
-+ struct dc_context *ctx = enc110->base.ctx;
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+
-+ /* stop generic packets 0 & 1 on HDMI */
-+ addr = LINK_REG(HDMI_GENERIC_PACKET_CONTROL0);
-+
-+ value = dm_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);
-+
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* stop generic packets 2 & 3 on HDMI */
-+ addr = LINK_REG(HDMI_GENERIC_PACKET_CONTROL1);
-+
-+ value = dm_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);
-+
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* stop AVI packet on HDMI */
-+ addr = LINK_REG(HDMI_INFOFRAME_CONTROL0);
-+
-+ value = dm_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);
-+
-+ dm_write_reg(ctx, addr, value);
-+}
-+void dce80_stream_encoder_update_dp_info_packets(
-+ struct stream_encoder *enc,
-+ const struct encoder_info_frame *info_frame)
-+{
-+ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
-+ struct dc_context *ctx = enc110->base.ctx;
-+ uint32_t addr = LINK_REG(DP_SEC_CNTL);
-+ uint32_t value;
-+
-+ if (info_frame->vsc.valid)
-+ dce80_update_generic_info_packet(
-+ enc110,
-+ 0,
-+ &info_frame->vsc);
-+
-+ /* enable/disable transmission of packet(s).
-+ * If enabled, packet transmission begins on the next frame
-+ */
-+ value = dm_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ info_frame->vsc.valid,
-+ DP_SEC_CNTL,
-+ DP_SEC_GSP0_ENABLE);
-+
-+ /* 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);
-+
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+void dce80_stream_encoder_stop_dp_info_packets(
-+ struct stream_encoder *enc)
-+{
-+ /* stop generic packets on DP */
-+ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
-+ struct dc_context *ctx = enc110->base.ctx;
-+ uint32_t addr = LINK_REG(DP_SEC_CNTL);
-+ uint32_t value = dm_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);
-+
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+void dce80_stream_encoder_dp_blank(
-+ struct stream_encoder *enc)
-+{
-+ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
-+ struct dc_context *ctx = enc110->base.ctx;
-+ uint32_t addr = LINK_REG(DP_VID_STREAM_CNTL);
-+ uint32_t value = dm_read_reg(ctx, addr);
-+ uint32_t retries = 0;
-+ uint32_t max_retries = DP_BLANK_MAX_RETRY * 10;
-+
-+ /* 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);
-+ dm_write_reg(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 = dm_read_reg(ctx, addr);
-+
-+ if (!get_reg_field_value(
-+ value,
-+ DP_VID_STREAM_CNTL,
-+ DP_VID_STREAM_STATUS))
-+ break;
-+
-+ dm_delay_in_microseconds(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.
-+ */
-+ addr = LINK_REG(DP_STEER_FIFO);
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(value, true, DP_STEER_FIFO, DP_STEER_FIFO_RESET);
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+/* output video stream to link encoder */
-+void dce80_stream_encoder_dp_unblank(
-+ struct stream_encoder *enc,
-+ const struct encoder_unblank_param *param)
-+{
-+ struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);
-+ struct dc_context *ctx = enc110->base.ctx;
-+ uint32_t addr;
-+ uint32_t value;
-+
-+ 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;
-+
-+ /* enable auto measurement */
-+ addr = LINK_REG(DP_VID_TIMING);
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(value, 0, DP_VID_TIMING, DP_VID_M_N_GEN_EN);
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* auto measurement need 1 full 0x8000 symbol cycle to kick in,
-+ * therefore program initial value for Mvid and Nvid
-+ */
-+ addr = LINK_REG(DP_VID_N);
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(value, n_vid, DP_VID_N, DP_VID_N);
-+ dm_write_reg(ctx, addr, value);
-+
-+ addr = LINK_REG(DP_VID_M);
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(value, m_vid, DP_VID_M, DP_VID_M);
-+ dm_write_reg(ctx, addr, value);
-+
-+ addr = LINK_REG(DP_VID_TIMING);
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(value, 1, DP_VID_TIMING, DP_VID_M_N_GEN_EN);
-+ dm_write_reg(ctx, addr, value);
-+ }
-+
-+ /* set DIG_START to 0x1 to resync FIFO */
-+ addr = LINK_REG(DIG_FE_CNTL);
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(value, 1, DIG_FE_CNTL, DIG_START);
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* switch DP encoder to CRTC data */
-+ addr = LINK_REG(DP_STEER_FIFO);
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(value, false, DP_STEER_FIFO, DP_STEER_FIFO_RESET);
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* wait 100us for DIG/DP logic to prime
-+ * (i.e. a few video lines)
-+ */
-+ dm_delay_in_microseconds(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 = LINK_REG(DP_VID_STREAM_CNTL);
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ true,
-+ DP_VID_STREAM_CNTL,
-+ DP_VID_STREAM_ENABLE);
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_stream_encoder.h b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_stream_encoder.h
-new file mode 100644
-index 0000000..f4645a8
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_stream_encoder.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
-+ *
-+ */
-+
-+#include "inc/stream_encoder.h"
-+
-+#ifndef __DC_STREAM_ENCODER_DCE80_H__
-+#define __DC_STREAM_ENCODER_DCE80_H__
-+
-+bool dce80_stream_encoder_construct(
-+ struct dce110_stream_encoder *enc110,
-+ struct dc_context *ctx,
-+ struct dc_bios *bp,
-+ enum engine_id eng_id,
-+ const struct dce110_stream_enc_registers *regs);
-+
-+/***** HW programming ***********/
-+/* setup stream encoder in dp mode */
-+void dce80_stream_encoder_dp_set_stream_attribute(
-+ struct stream_encoder *enc,
-+ struct dc_crtc_timing *crtc_timing);
-+
-+/* setup stream encoder in hdmi mode */
-+void dce80_stream_encoder_hdmi_set_stream_attribute(
-+ struct stream_encoder *enc,
-+ struct dc_crtc_timing *crtc_timing,
-+ bool enable_audio);
-+
-+/* setup stream encoder in dvi mode */
-+void dce80_stream_encoder_dvi_set_stream_attribute(
-+ struct stream_encoder *enc,
-+ struct dc_crtc_timing *crtc_timing,
-+ bool is_dual_link);
-+
-+/* set throttling for DP MST */
-+void dce80_stream_encoder_set_mst_bandwidth(
-+ struct stream_encoder *enc,
-+ struct fixed31_32 avg_time_slots_per_mtp);
-+
-+void dce80_stream_encoder_update_hdmi_info_packets(
-+ struct stream_encoder *enc,
-+ const struct encoder_info_frame *info_frame);
-+
-+void dce80_stream_encoder_stop_hdmi_info_packets(
-+ struct stream_encoder *enc);
-+
-+void dce80_stream_encoder_update_dp_info_packets(
-+ struct stream_encoder *enc,
-+ const struct encoder_info_frame *info_frame);
-+
-+void dce80_stream_encoder_stop_dp_info_packets(
-+ struct stream_encoder *enc);
-+
-+/* output blank/idle stream to link encoder */
-+void dce80_stream_encoder_dp_blank(
-+ struct stream_encoder *enc);
-+
-+/* output video stream to link encoder */
-+void dce80_stream_encoder_dp_unblank(
-+ struct stream_encoder *enc,
-+ const struct encoder_unblank_param *param);
-+
-+
-+#endif /* __DC_STREAM_ENCODER_DCE80_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_timing_generator.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_timing_generator.c
-new file mode 100644
-index 0000000..80391c2
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_timing_generator.c
-@@ -0,0 +1,241 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+/* include DCE8 register header files */
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_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 "../dce110/dce110_timing_generator.h"
-+#include "dce80_timing_generator.h"
-+
-+#include "../inc/timing_generator.h"
-+
-+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
-+};
-+
-+static const struct dce110_timing_generator_offsets reg_offsets[] = {
-+{
-+ .crtc = (mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL - mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{
-+ .crtc = (mmCRTC1_DCFE_MEM_LIGHT_SLEEP_CNTL - mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{
-+ .crtc = (mmCRTC2_DCFE_MEM_LIGHT_SLEEP_CNTL - mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{
-+ .crtc = (mmCRTC3_DCFE_MEM_LIGHT_SLEEP_CNTL - mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp = (mmDCP3_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{
-+ .crtc = (mmCRTC4_DCFE_MEM_LIGHT_SLEEP_CNTL - mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp = (mmDCP4_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{
-+ .crtc = (mmCRTC5_DCFE_MEM_LIGHT_SLEEP_CNTL - mmCRTC0_DCFE_MEM_LIGHT_SLEEP_CNTL),
-+ .dcp = (mmDCP5_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+}
-+};
-+
-+#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 CRTC_REG(reg) (reg + tg110->offsets.crtc)
-+#define DCP_REG(reg) (reg + tg110->offsets.dcp)
-+#define DMIF_REG(reg) (reg + tg110->offsets.dmif)
-+
-+void program_pix_dur(struct timing_generator *tg, uint32_t pix_clk_khz)
-+{
-+ uint64_t pix_dur;
-+ uint32_t addr = mmDMIF_PG0_DPG_PIPE_ARBITRATION_CONTROL1
-+ + DCE110TG_FROM_TG(tg)->offsets.dmif;
-+ uint32_t value = dm_read_reg(tg->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);
-+
-+ dm_write_reg(tg->ctx, addr, value);
-+}
-+
-+static void program_timing(struct timing_generator *tg,
-+ const struct dc_crtc_timing *timing,
-+ bool use_vbios)
-+{
-+ if (!use_vbios)
-+ program_pix_dur(tg, timing->pix_clk_khz);
-+
-+ dce110_tg_program_timing(tg, timing, use_vbios);
-+}
-+
-+static struct timing_generator_funcs dce80_tg_funcs = {
-+ .validate_timing = dce110_tg_validate_timing,
-+ .program_timing = program_timing,
-+ .enable_crtc = dce110_timing_generator_enable_crtc,
-+ .disable_crtc = dce110_timing_generator_disable_crtc,
-+ .is_counter_moving = dce110_timing_generator_is_counter_moving,
-+ .get_position = dce110_timing_generator_get_crtc_positions,
-+ .get_frame_count = dce110_timing_generator_get_vblank_counter,
-+ .set_early_control = dce110_timing_generator_set_early_control,
-+ .wait_for_state = dce110_tg_wait_for_state,
-+ .set_blank = dce110_tg_set_blank,
-+ .set_colors = dce110_tg_set_colors,
-+ .set_overscan_blank_color =
-+ dce110_timing_generator_set_overscan_color_black,
-+ .set_blank_color = dce110_timing_generator_program_blank_color,
-+ .disable_vga = dce110_timing_generator_disable_vga,
-+ .did_triggered_reset_occur =
-+ dce110_timing_generator_did_triggered_reset_occur,
-+ .setup_global_swap_lock =
-+ dce110_timing_generator_setup_global_swap_lock,
-+ .enable_reset_trigger = dce110_timing_generator_enable_reset_trigger,
-+ .disable_reset_trigger = dce110_timing_generator_disable_reset_trigger,
-+ .tear_down_global_swap_lock =
-+ dce110_timing_generator_tear_down_global_swap_lock,
-+
-+ /* DCE8.0 overrides */
-+ .enable_advanced_request =
-+ dce80_timing_generator_enable_advanced_request
-+};
-+
-+bool dce80_timing_generator_construct(
-+ struct dce110_timing_generator *tg110,
-+ struct adapter_service *as,
-+ struct dc_context *ctx,
-+ uint32_t instance,
-+ const struct dce110_timing_generator_offsets *offsets)
-+{
-+ if (!tg110)
-+ return false;
-+
-+ if (!as)
-+ return false;
-+
-+ tg110->controller_id = CONTROLLER_ID_D0 + instance;
-+ tg110->offsets = *offsets;
-+ tg110->derived_offsets = reg_offsets[instance];
-+
-+ tg110->base.funcs = &dce80_tg_funcs;
-+
-+ tg110->base.ctx = ctx;
-+ tg110->base.bp = dal_adapter_service_get_bios_parser(as);
-+
-+ tg110->max_h_total = CRTC_H_TOTAL__CRTC_H_TOTAL_MASK + 1;
-+ tg110->max_v_total = CRTC_V_TOTAL__CRTC_V_TOTAL_MASK + 1;
-+
-+ tg110->min_h_blank = 56;
-+ tg110->min_h_front_porch = 4;
-+ tg110->min_h_back_porch = 4;
-+
-+ return true;
-+}
-+
-+void dce80_timing_generator_enable_advanced_request(
-+ struct timing_generator *tg,
-+ bool enable,
-+ const struct dc_crtc_timing *timing)
-+{
-+ struct dce110_timing_generator *tg110 = DCE110TG_FROM_TG(tg);
-+ uint32_t addr = CRTC_REG(mmCRTC_START_LINE_CONTROL);
-+ uint32_t value = dm_read_reg(tg->ctx, addr);
-+
-+ if (enable && !DCE110TG_FROM_TG(tg)->disable_advanced_request) {
-+ 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 ((timing->v_sync_width + timing->v_front_porch) <= 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);
-+
-+ dm_write_reg(tg->ctx, addr, value);
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_timing_generator.h b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_timing_generator.h
-new file mode 100644
-index 0000000..0b88686
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_timing_generator.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 __DC_TIMING_GENERATOR_DCE80_H__
-+#define __DC_TIMING_GENERATOR_DCE80_H__
-+
-+
-+#include "../inc/timing_generator.h"
-+#include "../include/grph_object_id.h"
-+
-+/* DCE8.0 implementation inherits from DCE11.0 */
-+bool dce80_timing_generator_construct(
-+ struct dce110_timing_generator *tg,
-+ struct adapter_service *as,
-+ struct dc_context *ctx,
-+ uint32_t instance,
-+ const struct dce110_timing_generator_offsets *offsets);
-+
-+/******** HW programming ************/
-+void dce80_timing_generator_enable_advanced_request(
-+ struct timing_generator *tg,
-+ bool enable,
-+ const struct dc_crtc_timing *timing);
-+
-+
-+
-+#endif /* __DC_TIMING_GENERATOR_DCE80_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform.c
-new file mode 100644
-index 0000000..5654738
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform.c
-@@ -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
-+ *
-+ */
-+
-+#include "dm_services.h"
-+
-+/* include DCE8 register header files */
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_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 "dce80_transform.h"
-+
-+#include "dce80_transform_bit_depth.h"
-+
-+static struct transform_funcs dce80_transform_funcs = {
-+ .transform_power_up =
-+ dce80_transform_power_up,
-+ .transform_set_scaler =
-+ dce80_transform_set_scaler,
-+ .transform_set_scaler_bypass =
-+ dce80_transform_set_scaler_bypass,
-+ .transform_update_viewport =
-+ dce80_transform_update_viewport,
-+ .transform_set_scaler_filter =
-+ dce80_transform_set_scaler_filter,
-+ .transform_set_gamut_remap =
-+ dce80_transform_set_gamut_remap,
-+ .transform_set_pixel_storage_depth =
-+ dce80_transform_set_pixel_storage_depth,
-+ .transform_get_current_pixel_storage_depth =
-+ dce80_transform_get_current_pixel_storage_depth
-+};
-+
-+/*****************************************/
-+/* Constructor, Destructor */
-+/*****************************************/
-+
-+bool dce80_transform_construct(
-+ struct dce80_transform *xfm80,
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce80_transform_reg_offsets *reg_offsets)
-+{
-+ xfm80->base.ctx = ctx;
-+
-+ xfm80->base.inst = inst;
-+ xfm80->base.funcs = &dce80_transform_funcs;
-+
-+ xfm80->offsets = *reg_offsets;
-+
-+ xfm80->lb_pixel_depth_supported =
-+ LB_PIXEL_DEPTH_18BPP |
-+ LB_PIXEL_DEPTH_24BPP |
-+ LB_PIXEL_DEPTH_30BPP;
-+
-+ return true;
-+}
-+
-+bool dce80_transform_power_up(struct transform *xfm)
-+{
-+ return dce80_transform_power_up_line_buffer(xfm);
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform.h b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform.h
-new file mode 100644
-index 0000000..adcc54b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform.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_TRANSFORM_DCE80_H__
-+#define __DAL_TRANSFORM_DCE80_H__
-+
-+#include "inc/transform.h"
-+#include "include/grph_csc_types.h"
-+
-+#define TO_DCE80_TRANSFORM(transform)\
-+ container_of(transform, struct dce80_transform, base)
-+
-+struct dce80_transform_reg_offsets {
-+ uint32_t scl_offset;
-+ uint32_t crtc_offset;
-+ uint32_t dcp_offset;
-+ uint32_t lb_offset;
-+};
-+
-+struct dce80_transform {
-+ struct transform base;
-+ struct dce80_transform_reg_offsets offsets;
-+
-+ uint32_t lb_pixel_depth_supported;
-+};
-+
-+bool dce80_transform_construct(struct dce80_transform *xfm80,
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce80_transform_reg_offsets *offsets);
-+
-+bool dce80_transform_power_up(struct transform *xfm);
-+
-+/* SCALER RELATED */
-+bool dce80_transform_set_scaler(
-+ struct transform *xfm,
-+ const struct scaler_data *data);
-+
-+void dce80_transform_set_scaler_bypass(struct transform *xfm);
-+
-+bool dce80_transform_update_viewport(
-+ struct transform *xfm,
-+ const struct rect *view_port,
-+ bool is_fbc_attached);
-+
-+void dce80_transform_set_scaler_filter(
-+ struct transform *xfm,
-+ struct scaler_filter *filter);
-+
-+/* GAMUT RELATED */
-+void dce80_transform_set_gamut_remap(
-+ struct transform *xfm,
-+ const struct grph_csc_adjustment *adjust);
-+
-+/* BIT DEPTH RELATED */
-+bool dce80_transform_set_pixel_storage_depth(
-+ struct transform *xfm,
-+ enum lb_pixel_depth depth,
-+ const struct bit_depth_reduction_params *bit_depth_params);
-+
-+bool dce80_transform_get_current_pixel_storage_depth(
-+ struct transform *xfm,
-+ enum lb_pixel_depth *depth);
-+
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_bit_depth.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_bit_depth.c
-new file mode 100644
-index 0000000..1dc0dbc
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_bit_depth.c
-@@ -0,0 +1,841 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+/* include DCE8 register header files */
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+#include "dce80_transform.h"
-+
-+#include "include/logger_interface.h"
-+#include "include/fixed32_32.h"
-+
-+#define DCP_REG(reg)\
-+ (reg + xfm80->offsets.dcp_offset)
-+
-+#define LB_REG(reg)\
-+ (reg + xfm80->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 dce80_transform *xfm80,
-+ enum dc_color_depth depth);
-+
-+static bool set_round(
-+ struct dce80_transform *xfm80,
-+ enum dcp_out_trunc_round_mode mode,
-+ enum dcp_out_trunc_round_depth depth);
-+
-+static bool set_dither(
-+ struct dce80_transform *xfm80,
-+ 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);
-+
-+/**
-+ *******************************************************************************
-+ * dce80_transform_bit_depth_reduction_program
-+ *
-+ * @brief
-+ * Programs the DCP bit depth reduction registers (Clamp, Round/Truncate,
-+ * Dither) for dce80
-+ *
-+ * @param depth : bit depth to set the clamp to (should match denorm)
-+ *
-+ * @return
-+ * true if succeeds.
-+ *******************************************************************************
-+ */
-+static bool program_bit_depth_reduction(
-+ struct dce80_transform *xfm80,
-+ 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(xfm80, 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(xfm80,
-+ DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_12BIT);
-+
-+ set_dither(xfm80, 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(xfm80,
-+ DCP_OUT_TRUNC_ROUND_MODE_ROUND,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_10BIT);
-+
-+ set_dither(xfm80, 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(xfm80,
-+ DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_10BIT);
-+
-+ set_dither(xfm80, 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(xfm80,
-+ DCP_OUT_TRUNC_ROUND_MODE_TRUNCATE,
-+ DCP_OUT_TRUNC_ROUND_DEPTH_12BIT);
-+
-+ set_dither(xfm80, 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 dce80_transform *xfm80,
-+ 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 800 0000' */
-+ clamp_max = 0x3FC0;
-+ break;
-+ case COLOR_DEPTH_101010:
-+ /* 10bit MSB aligned on 14 bit bus '11 1111 1111 800' */
-+ 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);
-+
-+ dm_write_reg(xfm80->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);
-+
-+ dm_write_reg(xfm80->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);
-+
-+ dm_write_reg(xfm80->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 dce80_transform *xfm80,
-+ 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 */
-+ dm_write_reg(xfm80->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 dce80_transform *xfm80,
-+ 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 */
-+ dm_write_reg(xfm80->base.ctx,
-+ DCP_REG(mmDCP_SPATIAL_DITHER_CNTL),
-+ value);
-+
-+ return true;
-+}
-+
-+bool dce80_transform_get_max_num_of_supported_lines(
-+ struct dce80_transform *xfm80,
-+ 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(xfm80->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 dce80_transform_enable_alpha(
-+ struct dce80_transform *xfm80,
-+ bool enable)
-+{
-+ struct dc_context *ctx = xfm80->base.ctx;
-+ uint32_t value;
-+ uint32_t addr = LB_REG(mmLB_DATA_FORMAT);
-+
-+ value = dm_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);
-+
-+ dm_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 dce80_transform_get_next_lower_pixel_storage_depth(
-+ struct dce80_transform *xfm80,
-+ 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 (xfm80->lb_pixel_depth_supported & current_depth) {
-+ *lower_depth = current_depth;
-+ return true;
-+ }
-+ }
-+ return false;
-+}
-+
-+bool dce80_transform_is_prefetch_enabled(
-+ struct dce80_transform *xfm80)
-+{
-+ uint32_t value = dm_read_reg(
-+ xfm80->base.ctx, LB_REG(mmLB_DATA_FORMAT));
-+
-+ if (get_reg_field_value(value, LB_DATA_FORMAT, PREFETCH) == 1)
-+ return true;
-+
-+ return false;
-+}
-+
-+bool dce80_transform_get_current_pixel_storage_depth(
-+ struct transform *xfm,
-+ enum lb_pixel_depth *depth)
-+{
-+ struct dce80_transform *xfm80 = TO_DCE80_TRANSFORM(xfm);
-+ uint32_t value = 0;
-+
-+ if (depth == NULL)
-+ return false;
-+
-+ value = dm_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 dce80_transform *xfm80,
-+ enum dc_color_depth depth)
-+{
-+ uint32_t value = dm_read_reg(xfm80->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;
-+ }
-+
-+ dm_write_reg(xfm80->base.ctx,
-+ DCP_REG(mmDENORM_CONTROL),
-+ value);
-+
-+}
-+
-+bool dce80_transform_set_pixel_storage_depth(
-+ struct transform *xfm,
-+ enum lb_pixel_depth depth,
-+ const struct bit_depth_reduction_params *bit_depth_params)
-+{
-+ struct dce80_transform *xfm80 = TO_DCE80_TRANSFORM(xfm);
-+ bool ret = true;
-+ uint32_t value;
-+ enum dc_color_depth color_depth;
-+
-+ value = dm_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(xfm80, color_depth);
-+ ret = program_bit_depth_reduction(xfm80, color_depth);
-+
-+ set_reg_field_value(value, 0, LB_DATA_FORMAT, ALPHA_EN);
-+ dm_write_reg(
-+ xfm->ctx, LB_REG(mmLB_DATA_FORMAT), value);
-+ if (!(xfm80->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 dce80_transform_power_up_line_buffer(struct transform *xfm)
-+{
-+ struct dce80_transform *xfm80 = TO_DCE80_TRANSFORM(xfm);
-+ uint32_t value;
-+
-+ value = dm_read_reg(xfm80->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 DCE8 1712(0x6B0) Partitions: 720/960/1712*/
-+ set_reg_field_value(value, LB_TOTAL_NUMBER_OF_ENTRIES, LB_MEMORY_CTRL,
-+ LB_MEMORY_SIZE);
-+
-+ dm_write_reg(xfm80->base.ctx, LB_REG(mmLB_MEMORY_CTRL), value);
-+
-+ return true;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_bit_depth.h b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_bit_depth.h
-new file mode 100644
-index 0000000..af831f8
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_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_DCE80_H__
-+#define __DC_TRANSFORM_BIT_DEPTH_DCE80_H__
-+
-+#include "dce80_transform.h"
-+
-+bool dce80_transform_power_up_line_buffer(struct transform *xfm);
-+
-+bool dce80_transform_get_max_num_of_supported_lines(
-+ struct dce80_transform *xfm80,
-+ enum lb_pixel_depth depth,
-+ uint32_t pixel_width,
-+ uint32_t *lines);
-+
-+void dce80_transform_enable_alpha(
-+ struct dce80_transform *xfm80,
-+ bool enable);
-+
-+bool dce80_transform_get_next_lower_pixel_storage_depth(
-+ struct dce80_transform *xfm80,
-+ uint32_t display_bpp,
-+ enum lb_pixel_depth depth,
-+ enum lb_pixel_depth *lower_depth);
-+
-+bool dce80_transform_is_prefetch_enabled(
-+ struct dce80_transform *xfm80);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_gamut.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_gamut.c
-new file mode 100644
-index 0000000..df5db67
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_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 "dm_services.h"
-+
-+#include "dce80_transform.h"
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+#include "include/fixed31_32.h"
-+#include "basics/conversion.h"
-+#include "include/grph_object_id.h"
-+
-+enum {
-+ GAMUT_MATRIX_SIZE = 12
-+};
-+
-+#define DCP_REG(reg)\
-+ (reg + xfm80->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 dce80_transform *xfm80,
-+ const uint16_t *reg_val)
-+{
-+ struct dc_context *ctx = xfm80->base.ctx;
-+ uint32_t value = 0;
-+ uint32_t addr = DCP_REG(mmGAMUT_REMAP_CONTROL);
-+
-+ /* the register controls ovl also */
-+ value = dm_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);
-+
-+ dm_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);
-+
-+ dm_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);
-+
-+ dm_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);
-+
-+ dm_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);
-+
-+ dm_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);
-+
-+ dm_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);
-+ dm_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 dce80_transform_set_gamut_remap(
-+ struct transform *xfm,
-+ const struct grph_csc_adjustment *adjust)
-+{
-+ struct dce80_transform *xfm80 = TO_DCE80_TRANSFORM(xfm);
-+
-+ if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW ||
-+ adjust->temperature_divider == 0)
-+ program_gamut_remap(xfm80, 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(xfm80, arr_reg_val);
-+ }
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_scl.c b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_scl.c
-new file mode 100644
-index 0000000..62a3a04
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce80/dce80_transform_scl.c
-@@ -0,0 +1,814 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+/* include DCE8 register header files */
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+#include "dce80_transform.h"
-+
-+#define UP_SCALER_RATIO_MAX 16000
-+#define DOWN_SCALER_RATIO_MAX 250
-+#define SCALER_RATIO_DIVIDER 1000
-+
-+#define SCL_REG(reg)\
-+ (reg + xfm80->offsets.scl_offset)
-+
-+#define DCFE_REG(reg)\
-+ (reg + xfm80->offsets.crtc_offset)
-+
-+static void disable_enhanced_sharpness(struct dce80_transform *xfm80)
-+{
-+ uint32_t value;
-+
-+ value = dm_read_reg(xfm80->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);
-+
-+ dm_write_reg(xfm80->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 dce80_transform *xfm80,
-+ const struct scaler_data *data)
-+{
-+ struct dc_context *ctx = xfm80->base.ctx;
-+ uint32_t addr;
-+ uint32_t value;
-+
-+ if (data->taps.h_taps + data->taps.v_taps <= 2) {
-+ dce80_transform_set_scaler_bypass(&xfm80->base);
-+ return false;
-+ }
-+
-+ {
-+ addr = SCL_REG(mmSCL_MODE);
-+ value = dm_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);
-+
-+ dm_write_reg(ctx, addr, value);
-+ }
-+ {
-+ addr = SCL_REG(mmSCL_TAP_CONTROL);
-+ value = dm_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);
-+
-+ dm_write_reg(ctx, addr, value);
-+ }
-+ {
-+ addr = SCL_REG(mmSCL_CONTROL);
-+ value = dm_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. */
-+ dm_write_reg(ctx, addr, value);
-+ }
-+
-+ return true;
-+}
-+
-+/**
-+* Function:
-+* void program_overscan
-+*
-+* Purpose: Programs overscan border
-+* Input: overscan
-+*
-+* Output:
-+ void
-+*/
-+static void program_overscan(
-+ struct dce80_transform *xfm80,
-+ 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);
-+
-+ dm_write_reg(xfm80->base.ctx,
-+ SCL_REG(mmEXT_OVERSCAN_LEFT_RIGHT),
-+ overscan_left_right);
-+
-+ dm_write_reg(xfm80->base.ctx,
-+ SCL_REG(mmEXT_OVERSCAN_TOP_BOTTOM),
-+ overscan_top_bottom);
-+}
-+
-+static void program_two_taps_filter(
-+ struct dce80_transform *xfm80,
-+ 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 = dm_read_reg(xfm80->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 = dm_read_reg(xfm80->base.ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ enable ? 1 : 0,
-+ SCL_HORZ_FILTER_CONTROL,
-+ SCL_H_2TAP_HARDCODE_COEF_EN);
-+ }
-+
-+ dm_write_reg(xfm80->base.ctx, addr, value);
-+}
-+
-+static void set_coeff_update_complete(struct dce80_transform *xfm80)
-+{
-+ uint32_t value;
-+ uint32_t addr = SCL_REG(mmSCL_UPDATE);
-+
-+ value = dm_read_reg(xfm80->base.ctx, addr);
-+ set_reg_field_value(value, 1,
-+ SCL_UPDATE, SCL_COEF_UPDATE_COMPLETE);
-+ dm_write_reg(xfm80->base.ctx, addr, value);
-+}
-+
-+static void program_filter(
-+ struct dce80_transform *xfm80,
-+ 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_LIGHT_SLEEP_CNTL);
-+ pwr_ctrl_orig = dm_read_reg(xfm80->base.ctx, addr);
-+ pwr_ctrl_off = pwr_ctrl_orig;
-+ set_reg_field_value(
-+ pwr_ctrl_off,
-+ 1,
-+ DCFE_MEM_LIGHT_SLEEP_CNTL,
-+ SCL_LIGHT_SLEEP_DIS);
-+ dm_write_reg(xfm80->base.ctx, addr, pwr_ctrl_off);
-+
-+ /* Wait to disable gating: */
-+ for (i = 0;
-+ i < 10 &&
-+ get_reg_field_value(
-+ dm_read_reg(xfm80->base.ctx, addr),
-+ DCFE_MEM_LIGHT_SLEEP_CNTL,
-+ SCL_MEM_PWR_STATE);
-+ i++)
-+ dm_delay_in_microseconds(xfm80->base.ctx, 1);
-+
-+ ASSERT(i < 10);
-+
-+ select_addr = SCL_REG(mmSCL_COEF_RAM_SELECT);
-+ select = dm_read_reg(xfm80->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);
-+ dm_write_reg(xfm80->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;
-+ }
-+
-+ dm_write_reg(
-+ xfm80->base.ctx,
-+ SCL_REG(mmSCL_COEF_RAM_TAP_DATA),
-+ data);
-+ }
-+ }
-+
-+ ASSERT(coeffs_num == array_idx);
-+
-+ /* reset the power gating register */
-+ dm_write_reg(
-+ xfm80->base.ctx,
-+ DCFE_REG(mmDCFE_MEM_LIGHT_SLEEP_CNTL),
-+ pwr_ctrl_orig);
-+
-+ set_coeff_update_complete(xfm80);
-+}
-+
-+/*
-+ *
-+ * Populates an array with filter coefficients in 1.1.12 fixed point form
-+*/
-+static bool get_filter_coefficients(
-+ struct dce80_transform *xfm80,
-+ 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(
-+ xfm80->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 dce80_transform *xfm80,
-+ 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 DCE8 */
-+ 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(
-+ xfm80->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(
-+ xfm80,
-+ filter_params.taps,
-+ &filter_data,
-+ &filter_data_size))
-+ return false;
-+
-+ /* 3. Program the filter */
-+ program_filter(
-+ xfm80,
-+ 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(
-+ xfm80,
-+ filter_type,
-+ &filter_params,
-+ filter_data,
-+ filter_data_size);
-+ }
-+
-+ return true;
-+}
-+
-+static void program_viewport(
-+ struct dce80_transform *xfm80,
-+ const struct rect *view_port)
-+{
-+ struct dc_context *ctx = xfm80->base.ctx;
-+ uint32_t value = 0;
-+ uint32_t addr = 0;
-+
-+ addr = SCL_REG(mmVIEWPORT_START);
-+ value = dm_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);
-+ dm_write_reg(ctx, addr, value);
-+
-+ addr = SCL_REG(mmVIEWPORT_SIZE);
-+ value = dm_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);
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* TODO: add stereo support */
-+}
-+
-+static void calculate_inits(
-+ struct dce80_transform *xfm80,
-+ 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 dce80_transform *xfm80,
-+ 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);
-+ dm_write_reg(xfm80->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);
-+ dm_write_reg(xfm80->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);
-+ dm_write_reg(xfm80->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);
-+ dm_write_reg(xfm80->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);
-+ dm_write_reg(xfm80->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);
-+ dm_write_reg(xfm80->base.ctx, addr, value);
-+}
-+
-+static void get_viewport(
-+ struct dce80_transform *xfm80,
-+ struct rect *current_view_port)
-+{
-+ uint32_t value_start;
-+ uint32_t value_size;
-+
-+ if (current_view_port == NULL)
-+ return;
-+
-+ value_start = dm_read_reg(xfm80->base.ctx, SCL_REG(mmVIEWPORT_START));
-+ value_size = dm_read_reg(xfm80->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 dce80_transform_set_scaler(
-+ struct transform *xfm,
-+ const struct scaler_data *data)
-+{
-+ struct dce80_transform *xfm80 = TO_DCE80_TRANSFORM(xfm);
-+ bool is_scaling_required;
-+ struct dc_context *ctx = xfm->ctx;
-+
-+ {
-+ uint32_t addr = SCL_REG(mmSCL_BYPASS_CONTROL);
-+ uint32_t value = dm_read_reg(xfm->ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ SCL_BYPASS_CONTROL,
-+ SCL_BYPASS_MODE);
-+ dm_write_reg(xfm->ctx, addr, value);
-+ }
-+
-+ disable_enhanced_sharpness(xfm80);
-+
-+ /* 3. Program overscan */
-+ program_overscan(xfm80, &data->overscan);
-+
-+ /* 4. Program taps and configuration */
-+ is_scaling_required = setup_scaling_configuration(xfm80, data);
-+ if (is_scaling_required) {
-+ /* 5. Calculate and program ratio, filter initialization */
-+ struct scl_ratios_inits inits = { 0 };
-+
-+ calculate_inits(xfm80, data, &inits);
-+
-+ program_scl_ratios_inits(xfm80, &inits);
-+
-+ /* 6. Program vertical filters */
-+ if (data->taps.v_taps > 2) {
-+ program_two_taps_filter(xfm80, false, true);
-+
-+ if (!program_multi_taps_filter(xfm80, 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(xfm80, true, true);
-+
-+ /* 7. Program horizontal filters */
-+ if (data->taps.h_taps > 2) {
-+ program_two_taps_filter(xfm80, false, false);
-+
-+ if (!program_multi_taps_filter(xfm80, 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(xfm80, true, false);
-+ }
-+
-+ return true;
-+}
-+
-+void dce80_transform_set_scaler_bypass(struct transform *xfm)
-+{
-+ struct dce80_transform *xfm80 = TO_DCE80_TRANSFORM(xfm);
-+ uint32_t sclv_mode;
-+
-+ disable_enhanced_sharpness(xfm80);
-+
-+ sclv_mode = dm_read_reg(xfm->ctx, SCL_REG(mmSCL_MODE));
-+ set_reg_field_value(sclv_mode, 0, SCL_MODE, SCL_MODE);
-+ dm_write_reg(xfm->ctx, SCL_REG(mmSCL_MODE), sclv_mode);
-+}
-+
-+bool dce80_transform_update_viewport(
-+ struct transform *xfm,
-+ const struct rect *view_port,
-+ bool is_fbc_attached)
-+{
-+ struct dce80_transform *xfm80 = TO_DCE80_TRANSFORM(xfm);
-+ bool program_req = false;
-+ struct rect current_view_port;
-+
-+ if (view_port == NULL)
-+ return program_req;
-+
-+ get_viewport(xfm80, &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(xfm80, view_port);
-+ }
-+
-+ return program_req;
-+}
-+
-+void dce80_transform_set_scaler_filter(
-+ struct transform *xfm,
-+ struct scaler_filter *filter)
-+{
-+ xfm->filter = filter;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/Makefile b/drivers/gpu/drm/amd/dal/dc/gpio/Makefile
-index 2507bb5..a0d165c 100644
---- a/drivers/gpu/drm/amd/dal/dc/gpio/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/Makefile
-@@ -9,6 +9,18 @@ AMD_DAL_GPIO = $(addprefix $(AMDDALPATH)/dc/gpio/,$(GPIO))
-
- AMD_DAL_FILES += $(AMD_DAL_GPIO)
-
-+###############################################################################
-+# DCE 8x
-+###############################################################################
-+# all DCE8.x are derived from DCE8.0
-+ifdef CONFIG_DRM_AMD_DAL_DCE8_0
-+GPIO_DCE80 = hw_translate_dce80.o hw_factory_dce80.o \
-+ hw_ddc_dce80.o hw_hpd_dce80.o
-+
-+AMD_DAL_GPIO_DCE80 = $(addprefix $(AMDDALPATH)/dc/gpio/dce80/,$(GPIO_DCE80))
-+
-+AMD_DAL_FILES += $(AMD_DAL_GPIO_DCE80)
-+endif
-
- ###############################################################################
- # DCE 11x
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_ddc_dce80.c b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_ddc_dce80.c
-new file mode 100644
-index 0000000..850caeb
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_ddc_dce80.c
-@@ -0,0 +1,893 @@
-+/*
-+ * 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 "dm_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_dce80.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+/*
-+ * This unit
-+ */
-+
-+#define FROM_HW_DDC(ptr) \
-+ container_of((ptr), struct hw_ddc_dce80, base)
-+
-+#define FROM_HW_GPIO(ptr) \
-+ FROM_HW_DDC(container_of((ptr), struct hw_ddc, base))
-+
-+#define FROM_HW_GPIO_PIN(ptr) \
-+ FROM_HW_GPIO(container_of((ptr), struct hw_gpio, base))
-+
-+static void destruct(
-+ struct hw_ddc_dce80 *pin)
-+{
-+ dal_hw_ddc_destruct(&pin->base);
-+}
-+
-+static void destroy(
-+ struct hw_gpio_pin **ptr)
-+{
-+ struct hw_ddc_dce80 *pin = FROM_HW_GPIO_PIN(*ptr);
-+
-+ destruct(pin);
-+
-+ dm_free((*ptr)->ctx, pin);
-+
-+ *ptr = NULL;
-+}
-+
-+static void setup_i2c_polling(
-+ struct dc_context *ctx,
-+ const uint32_t addr,
-+ bool enable_detect,
-+ bool detect_mode)
-+{
-+ uint32_t value;
-+
-+ value = dm_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);
-+
-+ dm_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_dce80 *pin = FROM_HW_GPIO_PIN(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 = dm_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);
-+
-+ dm_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); */
-+ dm_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;
-+
-+ dm_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); */
-+ dm_sleep_in_milliseconds(ptr->ctx, 3);
-+ }
-+
-+ if (!scl_pd_dis) {
-+ scl_pd_dis = 1;
-+
-+ dm_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); */
-+ dm_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); */
-+ dm_sleep_in_milliseconds(ptr->ctx, 2);
-+
-+ /* set the I2C pad mode */
-+ /* read the register again,
-+ * some bits may have been changed */
-+ regval = dm_read_reg(ptr->ctx, addr);
-+
-+ set_reg_field_value(
-+ regval,
-+ 0,
-+ DC_GPIO_DDC1_MASK,
-+ AUX_PAD1_MODE);
-+
-+ dm_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);
-+
-+ dm_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, pin->addr.dc_i2c_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, pin->addr.dc_i2c_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, pin->addr.dc_i2c_ddc_setup, 0, 0);
-+ return GPIO_RESULT_OK;
-+ }
-+ break;
-+ }
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
-+}
-+
-+struct hw_ddc_dce80_init {
-+ struct hw_gpio_pin_reg hw_gpio_data_reg;
-+ struct hw_ddc_mask hw_ddc_mask;
-+ struct hw_ddc_dce80_addr hw_ddc_dce80_addr;
-+};
-+
-+static const struct hw_ddc_dce80_init
-+ hw_ddc_dce80_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_dce80_init
-+ hw_ddc_dce80_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 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_dce80 *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx)
-+{
-+ const struct hw_ddc_dce80_init *init;
-+
-+ if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!dal_hw_ddc_construct(&pin->base, id, en, ctx)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ pin->base.base.base.funcs = &funcs;
-+
-+ switch (id) {
-+ case GPIO_ID_DDC_DATA:
-+ init = hw_ddc_dce80_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_dce80_addr;
-+
-+ return true;
-+ case GPIO_ID_DDC_CLOCK:
-+ init = hw_ddc_dce80_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_dce80_addr;
-+
-+ return true;
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ }
-+
-+ dal_hw_ddc_destruct(&pin->base);
-+
-+ return false;
-+}
-+
-+struct hw_gpio_pin *dal_hw_ddc_dce80_create(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en)
-+{
-+ struct hw_ddc_dce80 *pin = dm_alloc(ctx, sizeof(struct hw_ddc_dce80));
-+
-+ if (!pin) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ if (construct(pin, id, en, ctx))
-+ return &pin->base.base.base;
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ dm_free(ctx, pin);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_ddc_dce80.h b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_ddc_dce80.h
-new file mode 100644
-index 0000000..f5bbb83
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_ddc_dce80.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_DCE80_H__
-+#define __DAL_HW_DDC_DCE80_H__
-+
-+struct hw_ddc_dce80_addr {
-+ uint32_t dc_i2c_ddc_setup;
-+};
-+
-+struct hw_ddc_dce80 {
-+ struct hw_ddc base;
-+ struct hw_ddc_dce80_addr addr;
-+};
-+
-+struct hw_gpio_pin *dal_hw_ddc_dce80_create(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en);
-+
-+#define DDC_DCE80_FROM_BASE(ddc_base) \
-+ container_of(HW_DDC_FROM_BASE(ddc_base), struct hw_ddc_dce80, base)
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_factory_dce80.c b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_factory_dce80.c
-new file mode 100644
-index 0000000..d1ea56d
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_factory_dce80.c
-@@ -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
-+ *
-+ */
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+
-+#include "dm_services.h"
-+#include "include/gpio_types.h"
-+#include "../hw_factory.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "hw_factory_dce80.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+#include "../hw_gpio_pin.h"
-+#include "../hw_gpio.h"
-+#include "../hw_gpio_pad.h"
-+#include "../hw_ddc.h"
-+#include "hw_ddc_dce80.h"
-+#include "../hw_hpd.h"
-+#include "hw_hpd_dce80.h"
-+
-+/*
-+ * This unit
-+ */
-+static const struct hw_factory_funcs funcs = {
-+ .create_ddc_data = dal_hw_ddc_dce80_create,
-+ .create_ddc_clock = dal_hw_ddc_dce80_create,
-+ .create_generic = NULL,
-+ .create_hpd = dal_hw_hpd_dce80_create,
-+ .create_gpio_pad = NULL,
-+ .create_sync = NULL,
-+ .create_gsl = NULL,
-+};
-+
-+void dal_hw_factory_dce80_init(
-+ struct hw_factory *factory)
-+{
-+ 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/dce80/hw_factory_dce80.h b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_factory_dce80.h
-new file mode 100644
-index 0000000..e78a8b3
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_factory_dce80.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_HW_FACTORY_DCE80_H__
-+#define __DAL_HW_FACTORY_DCE80_H__
-+
-+void dal_hw_factory_dce80_init(
-+ struct hw_factory *factory);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_hpd_dce80.c b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_hpd_dce80.c
-new file mode 100644
-index 0000000..67b249b
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_hpd_dce80.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 "dm_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_dce80.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+
-+/*
-+ * This unit
-+ */
-+
-+#define FROM_HW_HPD(ptr) \
-+ container_of((ptr), struct hw_hpd_dce80, base)
-+
-+#define FROM_HW_GPIO(ptr) \
-+ FROM_HW_HPD(container_of((ptr), struct hw_hpd, base))
-+
-+#define FROM_HW_GPIO_PIN(ptr) \
-+ FROM_HW_GPIO(container_of((ptr), struct hw_gpio, base))
-+
-+static void destruct(
-+ struct hw_hpd_dce80 *pin)
-+{
-+ dal_hw_hpd_destruct(&pin->base);
-+}
-+
-+static void destroy(
-+ struct hw_gpio_pin **ptr)
-+{
-+ struct hw_hpd_dce80 *pin = FROM_HW_GPIO_PIN(*ptr);
-+
-+ destruct(pin);
-+
-+ dm_free((*ptr)->ctx, pin);
-+
-+ *ptr = NULL;
-+}
-+
-+static enum gpio_result get_value(
-+ const struct hw_gpio_pin *ptr,
-+ uint32_t *value)
-+{
-+ struct hw_hpd_dce80 *pin = FROM_HW_GPIO_PIN(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 = dm_read_reg(
-+ ptr->ctx,
-+ pin->addr.DC_HPD_INT_STATUS);
-+
-+ hpd_delayed = get_reg_field_value(
-+ regval,
-+ DC_HPD1_INT_STATUS,
-+ DC_HPD1_SENSE_DELAYED);
-+
-+ hpd_sense = get_reg_field_value(
-+ regval,
-+ DC_HPD1_INT_STATUS,
-+ DC_HPD1_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_dce80 *pin = FROM_HW_GPIO_PIN(ptr);
-+
-+ if (!config_data)
-+ return GPIO_RESULT_INVALID_DATA;
-+
-+ {
-+ uint32_t value;
-+
-+ value = dm_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_HPD1_TOGGLE_FILT_CNTL,
-+ DC_HPD1_CONNECT_INT_DELAY);
-+
-+ set_reg_field_value(
-+ value,
-+ config_data->config.hpd.delay_on_disconnect / 10,
-+ DC_HPD1_TOGGLE_FILT_CNTL,
-+ DC_HPD1_DISCONNECT_INT_DELAY);
-+
-+ dm_write_reg(
-+ ptr->ctx,
-+ pin->addr.DC_HPD_TOGGLE_FILT_CNTL,
-+ value);
-+
-+ }
-+
-+ return GPIO_RESULT_OK;
-+}
-+
-+struct hw_gpio_generic_dce80_init {
-+ struct hw_gpio_pin_reg hw_gpio_data_reg;
-+ struct hw_hpd_dce80_addr addr;
-+};
-+
-+static const struct hw_gpio_generic_dce80_init
-+ hw_gpio_generic_dce80_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
-+ }
-+ },
-+ {
-+ mmDC_HPD1_INT_STATUS,
-+ mmDC_HPD1_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
-+ }
-+ },
-+ {
-+ mmDC_HPD2_INT_STATUS,
-+ mmDC_HPD2_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
-+ }
-+ },
-+ {
-+ mmDC_HPD3_INT_STATUS,
-+ mmDC_HPD3_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
-+ }
-+ },
-+ {
-+ mmDC_HPD4_INT_STATUS,
-+ mmDC_HPD4_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
-+ }
-+ },
-+ {
-+ mmDC_HPD5_INT_STATUS,
-+ mmDC_HPD5_TOGGLE_FILT_CNTL
-+ }
-+ },
-+ /* GPIO_HPD_1 */
-+ {
-+ {
-+ {
-+ 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
-+ }
-+ },
-+ {
-+ mmDC_HPD6_INT_STATUS,
-+ mmDC_HPD6_TOGGLE_FILT_CNTL
-+ }
-+ }
-+};
-+
-+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_dce80 *pin,
-+ enum gpio_id id,
-+ uint32_t en,
-+ struct dc_context *ctx)
-+{
-+ const struct hw_gpio_generic_dce80_init *init;
-+
-+ if (id != GPIO_ID_HPD) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if ((en < GPIO_HPD_MIN) || (en > GPIO_HPD_MAX)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!dal_hw_hpd_construct(&pin->base, id, en, ctx)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ pin->base.base.base.funcs = &funcs;
-+
-+ init = hw_gpio_generic_dce80_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_dce80_create(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en)
-+{
-+ struct hw_hpd_dce80 *pin = dm_alloc(ctx, sizeof(struct hw_hpd_dce80));
-+
-+ if (!pin) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ if (construct(pin, id, en, ctx))
-+ return &pin->base.base.base;
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ dm_free(ctx, pin);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_hpd_dce80.h b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_hpd_dce80.h
-new file mode 100644
-index 0000000..d74dbec
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_hpd_dce80.h
-@@ -0,0 +1,44 @@
-+/*
-+ * 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_DCE80_H__
-+#define __DAL_HW_HPD_DCE80_H__
-+
-+struct hw_hpd_dce80_addr {
-+ uint32_t DC_HPD_INT_STATUS;
-+ uint32_t DC_HPD_TOGGLE_FILT_CNTL;
-+};
-+
-+struct hw_hpd_dce80 {
-+ struct hw_hpd base;
-+ struct hw_hpd_dce80_addr addr;
-+};
-+
-+struct hw_gpio_pin *dal_hw_hpd_dce80_create(
-+ struct dc_context *ctx,
-+ enum gpio_id id,
-+ uint32_t en);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_translate_dce80.c b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_translate_dce80.c
-new file mode 100644
-index 0000000..9788106
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_translate_dce80.c
-@@ -0,0 +1,424 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+#include "include/gpio_types.h"
-+#include "../hw_translate.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "hw_translate_dce80.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+/*
-+ * This unit
-+ */
-+
-+#include "../hw_gpio_pin.h"
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+#include "smu/smu_7_0_1_d.h"
-+
-+/*
-+ * @brief
-+ * Returns index of first bit (starting with LSB) which is set
-+ */
-+static uint32_t index_from_vector(
-+ uint32_t vector)
-+{
-+ uint32_t result = 0;
-+ uint32_t mask = 1;
-+
-+ do {
-+ if (vector == mask)
-+ return result;
-+
-+ ++result;
-+ mask <<= 1;
-+ } while (mask);
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ return GPIO_ENUM_UNKNOWN;
-+}
-+
-+static bool offset_to_id(
-+ uint32_t offset,
-+ uint32_t mask,
-+ enum gpio_id *id,
-+ uint32_t *en)
-+{
-+ switch (offset) {
-+ /* 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:
-+ BREAK_TO_DEBUGGER();
-+ 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:
-+ BREAK_TO_DEBUGGER();
-+ 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:
-+ BREAK_TO_DEBUGGER();
-+ 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:
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+ break;
-+ /* GPIOPAD */
-+ case mmGPIOPAD_A:
-+ *id = GPIO_ID_GPIO_PAD;
-+ *en = index_from_vector(mask);
-+ return (*en <= GPIO_GPIO_PAD_MAX);
-+ /* 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:
-+ BREAK_TO_DEBUGGER();
-+ 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_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:
-+ BREAK_TO_DEBUGGER();
-+ 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:
-+ BREAK_TO_DEBUGGER();
-+ 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:
-+ BREAK_TO_DEBUGGER();
-+ 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:
-+ BREAK_TO_DEBUGGER();
-+ 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:
-+ BREAK_TO_DEBUGGER();
-+ 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:
-+ BREAK_TO_DEBUGGER();
-+ result = false;
-+ }
-+ break;
-+ case GPIO_ID_GPIO_PAD:
-+ info->offset = mmGPIOPAD_A;
-+ info->mask = (1 << en);
-+ result = (info->mask <= GPIO_GPIO_PAD_MAX);
-+ break;
-+ case GPIO_ID_VIP_PAD:
-+ default:
-+ BREAK_TO_DEBUGGER();
-+ 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;
-+}
-+
-+static const struct hw_translate_funcs funcs = {
-+ .offset_to_id = offset_to_id,
-+ .id_to_offset = id_to_offset,
-+};
-+
-+void dal_hw_translate_dce80_init(
-+ struct hw_translate *translate)
-+{
-+ translate->funcs = &funcs;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_translate_dce80.h b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_translate_dce80.h
-new file mode 100644
-index 0000000..374f2f3
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce80/hw_translate_dce80.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_HW_TRANSLATE_DCE80_H__
-+#define __DAL_HW_TRANSLATE_DCE80_H__
-+
-+void dal_hw_translate_dce80_init(
-+ struct hw_translate *tr);
-+
-+#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
-index e0f6ecf..9c8ff54 100644
---- a/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c
-@@ -40,6 +40,10 @@
- * Post-requisites: headers required by this unit
- */
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+#include "dce80/hw_factory_dce80.h"
-+#endif
-+
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
- #include "dce110/hw_factory_dce110.h"
- #endif
-@@ -61,6 +65,11 @@ bool dal_hw_factory_init(
- }
-
- switch (dce_version) {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ case DCE_VERSION_8_0:
-+ dal_hw_factory_dce80_init(factory);
-+ return true;
-+#endif
-
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- case DCE_VERSION_10_0:
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c
-index 215322e..d3c6bc8 100644
---- a/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c
-@@ -40,6 +40,10 @@
- * Post-requisites: headers required by this unit
- */
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+#include "dce80/hw_translate_dce80.h"
-+#endif
-+
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
- #include "dce110/hw_translate_dce110.h"
- #endif
-@@ -61,7 +65,11 @@ bool dal_hw_translate_init(
- }
-
- switch (dce_version) {
--
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ case DCE_VERSION_8_0:
-+ dal_hw_translate_dce80_init(translate);
-+ return true;
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- case DCE_VERSION_10_0:
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/Makefile b/drivers/gpu/drm/amd/dal/dc/gpu/Makefile
-index b481a6d..cb23508 100644
---- a/drivers/gpu/drm/amd/dal/dc/gpu/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/Makefile
-@@ -9,6 +9,18 @@ AMD_DAL_GPU = $(addprefix $(AMDDALPATH)/dc/gpu/,$(GPU))
-
- AMD_DAL_FILES += $(AMD_DAL_GPU)
-
-+###############################################################################
-+# DCE 80 family
-+###############################################################################
-+
-+ifdef CONFIG_DRM_AMD_DAL_DCE8_0
-+GPU_DCE80 = display_clock_dce80.o dc_clock_gating_dce80.o
-+
-+AMD_DAL_GPU_DCE80 = $(addprefix $(AMDDALPATH)/dc/gpu/dce80/,$(GPU_DCE80))
-+
-+AMD_DAL_FILES += $(AMD_DAL_GPU_DCE80)
-+endif
-+
-
- ###############################################################################
- # DCE 110 family
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce80/dc_clock_gating_dce80.c b/drivers/gpu/drm/amd/dal/dc/gpu/dce80/dc_clock_gating_dce80.c
-new file mode 100644
-index 0000000..5f57577
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce80/dc_clock_gating_dce80.c
-@@ -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
-+ *
-+ */
-+
-+#include "dm_services.h"
-+#include "dc_clock_gating_dce80.h"
-+
-+static void enable_hw_base_light_sleep(void)
-+{
-+ /* TODO: implement */
-+}
-+
-+static void disable_sw_manual_control_light_sleep(void)
-+{
-+ /* TODO: implement */
-+}
-+
-+static void enable_sw_manual_control_light_sleep(void)
-+{
-+ /* TODO: implement */
-+}
-+
-+void dal_dc_clock_gating_dce80_power_up(struct dc_context *ctx, bool enable)
-+{
-+ if (enable) {
-+ enable_hw_base_light_sleep();
-+ disable_sw_manual_control_light_sleep();
-+ } else {
-+ enable_sw_manual_control_light_sleep();
-+ }
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce80/dc_clock_gating_dce80.h b/drivers/gpu/drm/amd/dal/dc/gpu/dce80/dc_clock_gating_dce80.h
-new file mode 100644
-index 0000000..f4111c5
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce80/dc_clock_gating_dce80.h
-@@ -0,0 +1,31 @@
-+/*
-+ * 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_DCE80_H__
-+#define __DAL_DC_CLOCK_GATING_DCE80_H__
-+
-+void dal_dc_clock_gating_dce80_power_up(struct dc_context *ctx, bool enable);
-+
-+#endif /* __DAL_DC_CLOCK_GATING_DCE80_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce80/display_clock_dce80.c b/drivers/gpu/drm/amd/dal/dc/gpu/dce80/display_clock_dce80.c
-new file mode 100644
-index 0000000..760705f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce80/display_clock_dce80.c
-@@ -0,0 +1,925 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_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_dce80.h"
-+
-+#define DCE80_DFS_BYPASS_THRESHOLD_KHZ 100000
-+
-+/* Max clock values for each state indexed by "enum clocks_state": */
-+static struct state_dependent_clocks max_clks_by_state[] = {
-+/* ClocksStateInvalid - should not be used */
-+{ .display_clk_khz = 0, .pixel_clk_khz = 0 },
-+/* ClocksStateUltraLow - not expected to be used for DCE 8.0 */
-+{ .display_clk_khz = 0, .pixel_clk_khz = 0 },
-+/* ClocksStateLow */
-+{ .display_clk_khz = 352000, .pixel_clk_khz = 330000},
-+/* ClocksStateNominal */
-+{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 },
-+/* ClocksStatePerformance */
-+{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 } };
-+
-+
-+/* 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.*/
-+};
-+
-+/* 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 */
-+};
-+
-+/* 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*/
-+};
-+
-+static struct divider_range divider_ranges[DIVIDER_RANGE_MAX];
-+
-+#define FROM_DISPLAY_CLOCK(base) \
-+ container_of(base, struct display_clock_dce80, disp_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 uint32_t get_scaler_efficiency(struct min_clock_params *params)
-+{
-+ uint32_t scaler_efficiency = 3;
-+
-+ switch (params->scaler_efficiency) {
-+ case V_SCALER_EFFICIENCY_LB18BPP:
-+ case V_SCALER_EFFICIENCY_LB24BPP:
-+ scaler_efficiency = 4;
-+ break;
-+
-+ case V_SCALER_EFFICIENCY_LB30BPP:
-+ case V_SCALER_EFFICIENCY_LB36BPP:
-+ scaler_efficiency = 3;
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ return scaler_efficiency;
-+}
-+
-+static uint32_t get_actual_required_display_clk(
-+ struct display_clock_dce80 *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(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 get_validation_clock(struct display_clock *dc)
-+{
-+ uint32_t clk = 0;
-+ struct display_clock_dce80 *disp_clk = FROM_DISPLAY_CLOCK(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*/
-+ BREAK_TO_DEBUGGER();
-+ /* 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 uint32_t calc_single_display_min_clks(
-+ struct display_clock *base,
-+ struct min_clock_params *params,
-+ bool set_clk)
-+{
-+ struct fixed32_32 h_scale = dal_fixed32_32_from_int(1);
-+ struct fixed32_32 v_scale = dal_fixed32_32_from_int(1);
-+ uint32_t pix_clk_khz = params->requested_pixel_clock;
-+ uint32_t line_total = params->timing_info.h_total;
-+ uint32_t max_clk_khz = get_validation_clock(base);
-+ struct fixed32_32 deep_color_factor = get_deep_color_factor(params);
-+ uint32_t scaler_efficiency = get_scaler_efficiency(params);
-+ struct fixed32_32 v_filter_init;
-+ uint32_t v_filter_init_trunc;
-+ struct fixed32_32 v_filter_init_ceil;
-+ struct fixed32_32 src_lines_per_dst_line;
-+ uint32_t src_wdth_rnd_to_chunks;
-+ struct fixed32_32 scaling_coeff;
-+ struct fixed32_32 fx_disp_clk_khz;
-+ struct fixed32_32 fx_alt_disp_clk_khz;
-+ uint32_t disp_clk_khz;
-+ uint32_t alt_disp_clk_khz;
-+ struct display_clock_dce80 *dc = FROM_DISPLAY_CLOCK(base);
-+
-+
-+ if (0 != params->dest_view.height && 0 != params->dest_view.width) {
-+
-+ h_scale = dal_fixed32_32_from_fraction(
-+ params->source_view.width,
-+ params->dest_view.width);
-+ v_scale = dal_fixed32_32_from_fraction(
-+ params->source_view.height,
-+ params->dest_view.height);
-+ }
-+
-+ v_filter_init = dal_fixed32_32_from_fraction(
-+ params->scaling_info.v_taps, 2u);
-+ v_filter_init = dal_fixed32_32_add(v_filter_init,
-+ dal_fixed32_32_div_int(v_scale, 2));
-+ v_filter_init = dal_fixed32_32_add(v_filter_init,
-+ dal_fixed32_32_from_fraction(15, 10));
-+
-+
-+ 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);
-+ v_filter_init_ceil = dal_fixed32_32_div_int(v_filter_init_ceil, 3);
-+ v_filter_init_ceil = dal_fixed32_32_from_int(
-+ dal_fixed32_32_ceil(v_filter_init_ceil));
-+
-+ src_lines_per_dst_line = dal_fixed32_32_max(
-+ dal_fixed32_32_from_int(dal_fixed32_32_ceil(v_scale)),
-+ v_filter_init_ceil);
-+
-+ src_wdth_rnd_to_chunks =
-+ ((params->source_view.width - 1) / 128) * 128 + 256;
-+
-+ scaling_coeff = dal_fixed32_32_max(
-+ dal_fixed32_32_from_fraction(params->scaling_info.h_taps, 4),
-+ dal_fixed32_32_mul(
-+ dal_fixed32_32_from_fraction(
-+ params->scaling_info.v_taps,
-+ scaler_efficiency),
-+ h_scale));
-+
-+ scaling_coeff = dal_fixed32_32_max(scaling_coeff, h_scale);
-+
-+ fx_disp_clk_khz = dal_fixed32_32_mul(
-+ scaling_coeff, dal_fixed32_32_from_fraction(11, 10));
-+ if (0 != line_total) {
-+ struct fixed32_32 d_clk = dal_fixed32_32_mul_int(
-+ src_lines_per_dst_line, src_wdth_rnd_to_chunks);
-+ d_clk = dal_fixed32_32_div_int(d_clk, line_total);
-+ d_clk = dal_fixed32_32_mul(d_clk,
-+ dal_fixed32_32_from_fraction(11, 10));
-+ fx_disp_clk_khz = dal_fixed32_32_max(fx_disp_clk_khz, d_clk);
-+ }
-+
-+ fx_disp_clk_khz = dal_fixed32_32_max(fx_disp_clk_khz,
-+ dal_fixed32_32_mul(deep_color_factor,
-+ dal_fixed32_32_from_fraction(11, 10)));
-+
-+ fx_disp_clk_khz = dal_fixed32_32_mul_int(fx_disp_clk_khz, pix_clk_khz);
-+ fx_disp_clk_khz = dal_fixed32_32_mul(fx_disp_clk_khz,
-+ dal_fixed32_32_from_fraction(1005, 1000));
-+
-+ fx_alt_disp_clk_khz = scaling_coeff;
-+
-+ if (0 != line_total) {
-+ struct fixed32_32 d_clk = dal_fixed32_32_mul_int(
-+ src_lines_per_dst_line, src_wdth_rnd_to_chunks);
-+ d_clk = dal_fixed32_32_div_int(d_clk, line_total);
-+ d_clk = dal_fixed32_32_mul(d_clk,
-+ dal_fixed32_32_from_fraction(105, 100));
-+ fx_alt_disp_clk_khz = dal_fixed32_32_max(
-+ fx_alt_disp_clk_khz, d_clk);
-+ }
-+ fx_alt_disp_clk_khz = dal_fixed32_32_max(
-+ fx_alt_disp_clk_khz, fx_alt_disp_clk_khz);
-+
-+ fx_alt_disp_clk_khz = dal_fixed32_32_mul_int(
-+ fx_alt_disp_clk_khz, pix_clk_khz);
-+
-+ /* convert to integer*/
-+ disp_clk_khz = dal_fixed32_32_floor(fx_disp_clk_khz);
-+ alt_disp_clk_khz = dal_fixed32_32_floor(fx_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(
-+ dc, disp_clk_khz);
-+ alt_disp_clk_khz = get_actual_required_display_clk(
-+ dc, alt_disp_clk_khz);
-+ }
-+
-+ if ((disp_clk_khz > max_clk_khz) && (alt_disp_clk_khz <= max_clk_khz))
-+ disp_clk_khz = alt_disp_clk_khz;
-+
-+ return disp_clk_khz;
-+
-+}
-+
-+static uint32_t calc_cursor_bw_for_min_clks(struct min_clock_params *params)
-+{
-+
-+ struct fixed32_32 v_scale = dal_fixed32_32_from_int(1);
-+ struct fixed32_32 v_filter_ceiling;
-+ struct fixed32_32 src_lines_per_dst_line;
-+ struct fixed32_32 cursor_bw;
-+
-+
-+ /* DCE8 Mode Support and Mode Set Architecture Specification Rev 1.3
-+ 6.3.3 Cursor data Throughput requirement on DISPCLK
-+ The MCIF to DCP cursor data return throughput is one pixel per DISPCLK
-+ shared among the display heads.
-+ If (Total Cursor Bandwidth in pixels for All heads> DISPCLK)
-+ The mode is not supported
-+ Cursor Bandwidth in Pixels = Cursor Width *
-+ (SourceLinesPerDestinationLine / Line Time)
-+ Assuming that Cursor Width = 128
-+ */
-+ /*In the hardware doc they mention an Interlace Factor
-+ It is not used here because we have already used it when
-+ calculating destination view*/
-+ if (0 != params->dest_view.height)
-+ v_scale = dal_fixed32_32_from_fraction(
-+ params->source_view.height,
-+ params->dest_view.height);
-+
-+ {
-+ /*Do: Vertical Filter Init = 0.5 + VTAPS/2 + VSR/2 * Interlace Factor*/
-+ /*Interlace Factor is included in verticalScaleRatio*/
-+ struct fixed32_32 v_filter = dal_fixed32_32_add(
-+ dal_fixed32_32_from_fraction(params->scaling_info.v_taps, 2),
-+ dal_fixed32_32_div_int(v_scale, 2));
-+ /*Do : Ceiling (Vertical Filter Init, 2)/3 )*/
-+ v_filter_ceiling = dal_fixed32_32_div_int(v_filter, 2);
-+ v_filter_ceiling = dal_fixed32_32_mul_int(
-+ dal_fixed32_32_from_int(dal_fixed32_32_ceil(v_filter_ceiling)),
-+ 2);
-+ v_filter_ceiling = dal_fixed32_32_div_int(v_filter_ceiling, 3);
-+ }
-+ /*Do : MAX( CeilCeiling (VSR), Ceiling (Vertical Filter Init, 2)/3 )*/
-+ /*Do : SourceLinesPerDestinationLine =
-+ * MAX( Ceiling (VSR), Ceiling (Vertical Filter Init, 2)/3 )*/
-+ src_lines_per_dst_line = dal_fixed32_32_max(v_scale, v_filter_ceiling);
-+
-+ if ((params->requested_pixel_clock != 0) &&
-+ (params->timing_info.h_total != 0)) {
-+ /* pixelClock is in units of KHz. Calc lineTime in us*/
-+ struct fixed32_32 inv_line_time = dal_fixed32_32_from_fraction(
-+ params->requested_pixel_clock,
-+ params->timing_info.h_total);
-+ cursor_bw = dal_fixed32_32_mul(
-+ dal_fixed32_32_mul_int(inv_line_time, 128),
-+ src_lines_per_dst_line);
-+ }
-+
-+ /* convert to integer*/
-+ return dal_fixed32_32_floor(cursor_bw);
-+}
-+
-+static bool validate(
-+ struct display_clock *dc,
-+ struct min_clock_params *params)
-+{
-+ uint32_t max_clk_khz = get_validation_clock(dc);
-+ uint32_t req_clk_khz;
-+
-+ if (params == NULL)
-+ return false;
-+
-+ req_clk_khz = calc_single_display_min_clks(dc, params, false);
-+
-+ return (req_clk_khz <= max_clk_khz);
-+}
-+
-+static uint32_t calculate_min_clock(
-+ struct display_clock *dc,
-+ uint32_t path_num,
-+ struct min_clock_params *params)
-+{
-+ uint32_t i;
-+ uint32_t validation_clk_khz = get_validation_clock(dc);
-+ uint32_t min_clk_khz = validation_clk_khz;
-+ uint32_t max_clk_khz = 0;
-+ uint32_t total_cursor_bw = 0;
-+ struct display_clock_dce80 *disp_clk = FROM_DISPLAY_CLOCK(dc);
-+
-+
-+ if (disp_clk->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(
-+ dc, params, true);
-+
-+ /* update the max required clock found*/
-+ if (disp_clk_khz > max_clk_khz)
-+ max_clk_khz = disp_clk_khz;
-+
-+ disp_clk_khz = calc_cursor_bw_for_min_clks(params);
-+
-+ total_cursor_bw += disp_clk_khz;
-+
-+ params++;
-+
-+ }
-+ }
-+
-+ max_clk_khz = (total_cursor_bw > max_clk_khz) ? total_cursor_bw :
-+ max_clk_khz;
-+
-+ min_clk_khz = max_clk_khz;
-+
-+ /*"Cursor data Throughput requirement on DISPCLK is now a factor,
-+ * need to change the code */
-+ ASSERT(total_cursor_bw < validation_clk_khz);
-+
-+ if (min_clk_khz > validation_clk_khz)
-+ min_clk_khz = validation_clk_khz;
-+ else if (min_clk_khz < dc->min_display_clk_threshold_khz)
-+ min_clk_khz = dc->min_display_clk_threshold_khz;
-+
-+ return min_clk_khz;
-+}
-+
-+static void set_clock(
-+ struct display_clock *dc,
-+ uint32_t requested_clk_khz)
-+{
-+ struct bp_pixel_clock_parameters pxl_clk_params;
-+ struct display_clock_dce80 *disp_clk = FROM_DISPLAY_CLOCK(dc);
-+ struct dc_bios *bp = dal_adapter_service_get_bios_parser(dc->as);
-+
-+ /* Prepare to program display clock*/
-+ dm_memset(&pxl_clk_params, 0, sizeof(pxl_clk_params));
-+
-+ pxl_clk_params.target_pixel_clock = requested_clk_khz;
-+ pxl_clk_params.pll_id = dc->id;
-+
-+ bp->funcs->program_display_engine_pll(bp, &pxl_clk_params);
-+
-+ if (disp_clk->dfs_bypass_enabled) {
-+
-+ /* Cache the fixed display clock*/
-+ disp_clk->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)
-+ disp_clk->cur_min_clks_state = CLOCKS_STATE_NOMINAL;
-+}
-+
-+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_dce80 *disp_clk = FROM_DISPLAY_CLOCK(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 = dm_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 void set_clock_state(
-+ struct display_clock *dc,
-+ struct display_clock_state clk_state)
-+{
-+ struct display_clock_dce80 *disp_clk = FROM_DISPLAY_CLOCK(dc);
-+
-+ disp_clk->clock_state = clk_state;
-+}
-+static struct display_clock_state get_clock_state(
-+ struct display_clock *dc)
-+{
-+ struct display_clock_dce80 *disp_clk = FROM_DISPLAY_CLOCK(dc);
-+
-+ return disp_clk->clock_state;
-+}
-+
-+static enum clocks_state get_min_clocks_state(struct display_clock *dc)
-+{
-+ struct display_clock_dce80 *disp_clk = FROM_DISPLAY_CLOCK(dc);
-+
-+ return disp_clk->cur_min_clks_state;
-+}
-+
-+static enum clocks_state get_required_clocks_state
-+ (struct display_clock *dc,
-+ struct state_dependent_clocks *req_clocks)
-+{
-+ int32_t i;
-+ struct display_clock_dce80 *disp_clk = FROM_DISPLAY_CLOCK(dc);
-+ enum clocks_state low_req_clk = disp_clk->max_clks_state;
-+
-+ if (!req_clocks) {
-+ /* NULL pointer*/
-+ BREAK_TO_DEBUGGER();
-+ 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 bool set_min_clocks_state(
-+ struct display_clock *dc,
-+ enum clocks_state clocks_state)
-+{
-+ struct display_clock_dce80 *disp_clk = FROM_DISPLAY_CLOCK(dc);
-+
-+ if (clocks_state > disp_clk->max_clks_state) {
-+ /*Requested state exceeds max supported state.*/
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ } else if (clocks_state == disp_clk->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;
-+ }
-+
-+ disp_clk->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_dce80 *disp_clk = FROM_DISPLAY_CLOCK(dc);
-+
-+ /* ASSERT DP Reference Clock source is from DFS*/
-+ dp_ref_clk_cntl_value = dm_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 = dm_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 store_max_clocks_state(
-+ struct display_clock *dc,
-+ enum clocks_state max_clocks_state)
-+{
-+ struct display_clock_dce80 *disp_clk = FROM_DISPLAY_CLOCK(dc);
-+
-+ switch (max_clocks_state) {
-+ case CLOCKS_STATE_LOW:
-+ case CLOCKS_STATE_NOMINAL:
-+ case CLOCKS_STATE_PERFORMANCE:
-+ case CLOCKS_STATE_ULTRA_LOW:
-+ disp_clk->max_clks_state = max_clocks_state;
-+ break;
-+
-+ case CLOCKS_STATE_INVALID:
-+ default:
-+ /*Invalid Clocks State!*/
-+ BREAK_TO_DEBUGGER();
-+ break;
-+ }
-+}
-+
-+static void display_clock_ss_construct(
-+ struct display_clock_dce80 *disp_clk,
-+ struct adapter_service *as)
-+{
-+ uint32_t ss_entry_num = dal_adapter_service_get_ss_info_num(as,
-+ AS_SIGNAL_TYPE_GPU_PLL);
-+
-+ /*Read SS Info from VBIOS SS Info table for DP Reference Clock spread.*/
-+ if (ss_entry_num > 0) {/* Should be only one entry */
-+ struct spread_spectrum_info ss_info;
-+ bool res;
-+
-+ dm_memset(&ss_info, 0, sizeof(struct spread_spectrum_info));
-+
-+ res = dal_adapter_service_get_ss_info(as,
-+ AS_SIGNAL_TYPE_GPU_PLL, 0, &ss_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 (res && ss_info.spread_spectrum_percentage != 0) {
-+ disp_clk->ss_on_gpu_pll = true;
-+ disp_clk->gpu_pll_ss_divider =
-+ ss_info.spread_percentage_divider;
-+ if (ss_info.type.CENTER_MODE == 0)
-+ /* Currently we need only SS
-+ * percentage for down-spread*/
-+ disp_clk->gpu_pll_ss_percentage =
-+ ss_info.spread_spectrum_percentage;
-+ }
-+ }
-+}
-+
-+static bool display_clock_integrated_info_construct(
-+ struct display_clock_dce80 *disp_clk,
-+ struct adapter_service *as)
-+{
-+ struct integrated_info info;
-+ struct firmware_info fw_info;
-+ bool res;
-+ uint32_t i;
-+
-+ res = dal_adapter_service_get_integrated_info(as, &info);
-+
-+ disp_clk->dentist_vco_freq_khz = info.dentist_vco_freq;
-+ if (disp_clk->dentist_vco_freq_khz == 0) {
-+ dal_adapter_service_get_firmware_info(as, &fw_info);
-+ disp_clk->dentist_vco_freq_khz =
-+ fw_info.smu_gpu_pll_output_freq;
-+ if (disp_clk->dentist_vco_freq_khz == 0)
-+ disp_clk->dentist_vco_freq_khz = 3600000;
-+ }
-+ disp_clk->disp_clk.min_display_clk_threshold_khz =
-+ disp_clk->dentist_vco_freq_khz / 64;
-+
-+ if (!res)
-+ return false;
-+
-+ /* TODO: initialise disp_clk->dfs_bypass_disp_clk */
-+
-+ /*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;
-+ }
-+ /*invalid input from bios*/
-+ ASSERT(info.disp_clk_voltage[i].max_supported_clk >= 100000);
-+ }
-+ disp_clk->dfs_bypass_enabled =
-+ dal_adapter_service_is_dfs_bypass_enabled(as) &&
-+ dal_adapter_service_is_feature_supported(
-+ FEATURE_ENABLE_DFS_BYPASS);
-+
-+ disp_clk->use_max_disp_clk =
-+ dal_adapter_service_is_feature_supported(
-+ FEATURE_USE_MAX_DISPLAY_CLK);
-+ return true;
-+}
-+
-+static uint32_t get_dfs_bypass_threshold(struct display_clock *dc)
-+{
-+ return DCE80_DFS_BYPASS_THRESHOLD_KHZ;
-+}
-+
-+static void destroy(struct display_clock **dc)
-+{
-+ struct display_clock_dce80 *disp_clk;
-+
-+ disp_clk = FROM_DISPLAY_CLOCK(*dc);
-+ dm_free((*dc)->ctx, disp_clk);
-+ *dc = NULL;
-+}
-+
-+static const struct display_clock_funcs funcs = {
-+ .calculate_min_clock = calculate_min_clock,
-+ .destroy = destroy,
-+ .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 =
-+ dal_display_clock_base_set_dp_ref_clock_source,
-+ .set_min_clocks_state = set_min_clocks_state,
-+ .store_max_clocks_state = store_max_clocks_state,
-+ .validate = validate,
-+};
-+
-+static bool display_clock_construct(
-+ struct dc_context *ctx,
-+ struct display_clock_dce80 *disp_clk,
-+ struct adapter_service *as)
-+{
-+ struct display_clock *dc_base = &disp_clk->disp_clk;
-+
-+ if (NULL == as)
-+ return false;
-+
-+ if (!dal_display_clock_construct_base(dc_base, ctx, as))
-+ return false;
-+
-+ dc_base->funcs = &funcs;
-+ /*
-+ * set_dp_ref_clock_source
-+ * set_clock_state
-+ * get_clock_state
-+ * get_dfs_bypass_threshold
-+ */
-+
-+ disp_clk->gpu_pll_ss_percentage = 0;
-+ disp_clk->gpu_pll_ss_divider = 1000;
-+ disp_clk->ss_on_gpu_pll = false;
-+ disp_clk->dfs_bypass_enabled = false;
-+ disp_clk->dfs_bypass_disp_clk = 0;
-+ disp_clk->use_max_disp_clk = true;/* false will hang the system! */
-+
-+ disp_clk->disp_clk.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_Dce50::StoreMaxClocksState(). This call will come in
-+ * on PPLIB init. This is from DCE5x. in case HW wants to use mixed method.*/
-+ disp_clk->max_clks_state = CLOCKS_STATE_NOMINAL;
-+/* 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.*/
-+ disp_clk->cur_min_clks_state = CLOCKS_STATE_INVALID;
-+
-+ display_clock_ss_construct(disp_clk, as);
-+
-+ if (!display_clock_integrated_info_construct(disp_clk, as)) {
-+ dal_logger_write(dc_base->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Cannot obtain VBIOS integrated info");
-+ }
-+
-+ 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);
-+ return true;
-+}
-+
-+struct display_clock *dal_display_clock_dce80_create(
-+ struct dc_context *ctx,
-+ struct adapter_service *as)
-+{
-+ struct display_clock_dce80 *disp_clk;
-+
-+ disp_clk = dm_alloc(ctx, sizeof(struct display_clock_dce80));
-+
-+ if (disp_clk == NULL)
-+ return NULL;
-+
-+ if (display_clock_construct(ctx, disp_clk, as))
-+ return &disp_clk->disp_clk;
-+
-+ dm_free(ctx, disp_clk);
-+ return NULL;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce80/display_clock_dce80.h b/drivers/gpu/drm/amd/dal/dc/gpu/dce80/display_clock_dce80.h
-new file mode 100644
-index 0000000..2d68704
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce80/display_clock_dce80.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_DISPLAY_CLOCK_DCE80_H__
-+#define __DAL_DISPLAY_CLOCK_DCE80_H__
-+
-+#include "gpu/display_clock.h"
-+
-+struct display_clock_dce80 {
-+ struct display_clock disp_clk;
-+ /* DFS input - GPUPLL VCO frequency - from VBIOS Firmware info. */
-+ uint32_t dentist_vco_freq_khz;
-+ /* 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;
-+ /* Max display block clocks state*/
-+ enum clocks_state max_clks_state;
-+ /* Current minimum display block clocks state*/
-+ enum clocks_state cur_min_clks_state;
-+ /* DFS-bypass feature variable
-+ Cache the status of DFS-bypass feature*/
-+ bool dfs_bypass_enabled;
-+ /* 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;
-+ bool use_max_disp_clk;
-+ struct display_clock_state clock_state;
-+};
-+
-+struct display_clock *dal_display_clock_dce80_create(
-+ struct dc_context *ctx,
-+ struct adapter_service *as);
-+
-+#endif /* __DAL_DISPLAY_CLOCK_DCE80_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/Makefile b/drivers/gpu/drm/amd/dal/dc/i2caux/Makefile
-index 390d83d..fc76821 100644
---- a/drivers/gpu/drm/amd/dal/dc/i2caux/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/Makefile
-@@ -9,6 +9,17 @@ AMD_DAL_I2CAUX = $(addprefix $(AMDDALPATH)/dc/i2caux/,$(I2CAUX))
-
- AMD_DAL_FILES += $(AMD_DAL_I2CAUX)
-
-+###############################################################################
-+# DCE 8x family
-+###############################################################################
-+ifdef CONFIG_DRM_AMD_DAL_DCE8_0
-+I2CAUX_DCE80 = i2caux_dce80.o i2c_hw_engine_dce80.o \
-+ i2c_sw_engine_dce80.o aux_engine_dce80.o
-+
-+AMD_DAL_I2CAUX_DCE80 = $(addprefix $(AMDDALPATH)/dc/i2caux/dce80/,$(I2CAUX_DCE80))
-+
-+AMD_DAL_FILES += $(AMD_DAL_I2CAUX_DCE80)
-+endif
-
- ###############################################################################
- # DCE 11x family
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/aux_engine_dce80.c b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/aux_engine_dce80.c
-new file mode 100644
-index 0000000..a4fc2cd
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/aux_engine_dce80.c
-@@ -0,0 +1,740 @@
-+/*
-+ * 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 "dm_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_dce80.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+
-+/*
-+ * This unit
-+ */
-+
-+/*
-+ * @brief
-+ * Cast 'struct aux_engine *'
-+ * to 'struct aux_engine_dce80 *'
-+ */
-+#define FROM_AUX_ENGINE(ptr) \
-+ container_of((ptr), struct aux_engine_dce80, base)
-+
-+/*
-+ * @brief
-+ * Cast 'struct engine *'
-+ * to 'struct aux_engine_dce80 *'
-+ */
-+#define FROM_ENGINE(ptr) \
-+ FROM_AUX_ENGINE(container_of((ptr), struct aux_engine, base))
-+
-+static void release_engine(
-+ struct engine *engine)
-+{
-+ struct aux_engine_dce80 *aux_engine = FROM_ENGINE(engine);
-+
-+ const uint32_t addr = aux_engine->addr.AUX_ARB_CONTROL;
-+
-+ uint32_t value = dm_read_reg(engine->ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_ARB_CONTROL,
-+ AUX_SW_DONE_USING_AUX_REG);
-+
-+ dm_write_reg(engine->ctx, addr, value);
-+}
-+
-+static void destruct(
-+ struct aux_engine_dce80 *engine);
-+
-+static void destroy(
-+ struct aux_engine **aux_engine)
-+{
-+ struct aux_engine_dce80 *engine = FROM_AUX_ENGINE(*aux_engine);
-+
-+ destruct(engine);
-+
-+ dm_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_dce80 *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 = dm_read_reg(engine->base.ctx, addr);
-+
-+ field = get_reg_field_value(
-+ value,
-+ AUX_CONTROL,
-+ AUX_EN);
-+
-+ if (field == 0) {
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_CONTROL,
-+ AUX_EN);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+ }
-+ }
-+
-+ /* request SW to access AUX */
-+ {
-+ const uint32_t addr = aux_engine->addr.AUX_ARB_CONTROL;
-+
-+ value = dm_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_ARB_CONTROL,
-+ AUX_SW_USE_AUX_REG_REQ);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+
-+ value = dm_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_dce80 *aux_engine = FROM_AUX_ENGINE(engine);
-+
-+ const uint32_t addr = aux_engine->addr.AUX_CONTROL;
-+
-+ uint32_t value = dm_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);
-+
-+ dm_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_dce80 *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 = dm_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUXN_IMPCAL,
-+ AUXN_CALOUT_ERROR_AK);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUXN_IMPCAL,
-+ AUXN_CALOUT_ERROR_AK);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+ }
-+ {
-+ const uint32_t addr = mmAUXP_IMPCAL;
-+
-+ value = dm_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUXP_IMPCAL,
-+ AUXP_CALOUT_ERROR_AK);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUXP_IMPCAL,
-+ AUXP_CALOUT_ERROR_AK);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+ }
-+
-+ /* force_default_calibrate */
-+ {
-+ const uint32_t addr = mmAUXN_IMPCAL;
-+
-+ value = dm_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUXN_IMPCAL,
-+ AUXN_IMPCAL_ENABLE);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUXN_IMPCAL,
-+ AUXN_IMPCAL_OVERRIDE_ENABLE);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+ }
-+ {
-+ const uint32_t addr = mmAUXP_IMPCAL;
-+
-+ value = dm_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUXP_IMPCAL,
-+ AUXP_IMPCAL_OVERRIDE_ENABLE);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUXP_IMPCAL,
-+ AUXP_IMPCAL_OVERRIDE_ENABLE);
-+
-+ dm_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 = dm_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);
-+
-+ dm_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 = dm_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);
-+
-+ dm_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);
-+
-+ dm_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);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+
-+ if (request->length) {
-+ set_reg_field_value(
-+ value,
-+ request->length - 1,
-+ AUX_SW_DATA,
-+ AUX_SW_DATA);
-+
-+ dm_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);
-+
-+ dm_write_reg(
-+ engine->base.ctx, addr, value);
-+
-+ ++i;
-+ }
-+ }
-+ }
-+
-+ {
-+ const uint32_t addr = aux_engine->addr.AUX_INTERRUPT_CONTROL;
-+
-+ value = dm_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_INTERRUPT_CONTROL,
-+ AUX_SW_DONE_ACK);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+ }
-+
-+ {
-+ const uint32_t addr = aux_engine->addr.AUX_SW_CONTROL;
-+
-+ value = dm_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_SW_CONTROL,
-+ AUX_SW_GO);
-+
-+ dm_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_dce80 *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 = dm_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 = dm_read_reg(engine->base.ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ AUX_SW_DATA,
-+ AUX_SW_INDEX);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_SW_DATA,
-+ AUX_SW_AUTOINCREMENT_DISABLE);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ AUX_SW_DATA,
-+ AUX_SW_DATA_RW);
-+
-+ dm_write_reg(engine->base.ctx, addr, value);
-+
-+ value = dm_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 = dm_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_dce80 *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 = dm_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;
-+
-+ dm_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_dce80 *engine,
-+ const struct aux_engine_dce80_create_arg *arg)
-+{
-+ int32_t offset;
-+
-+ if (arg->engine_id >= sizeof(aux_channel_offset) / sizeof(int32_t)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ if (!dal_aux_engine_construct(&engine->base, arg->ctx)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+ engine->base.base.funcs = &engine_funcs;
-+ engine->base.funcs = &aux_engine_funcs;
-+ offset = aux_channel_offset[arg->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 = arg->timeout_period;
-+
-+ return true;
-+}
-+
-+static void destruct(
-+ struct aux_engine_dce80 *engine)
-+{
-+ dal_aux_engine_destruct(&engine->base);
-+}
-+
-+struct aux_engine *dal_aux_engine_dce80_create(
-+ const struct aux_engine_dce80_create_arg *arg)
-+{
-+ struct aux_engine_dce80 *engine;
-+
-+ if (!arg) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ engine = dm_alloc(arg->ctx, sizeof(struct aux_engine_dce80));
-+
-+ if (!engine) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ if (construct(engine, arg))
-+ return &engine->base;
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ dm_free(arg->ctx, engine);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/aux_engine_dce80.h b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/aux_engine_dce80.h
-new file mode 100644
-index 0000000..8523c45
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/aux_engine_dce80.h
-@@ -0,0 +1,54 @@
-+/*
-+ * 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_DCE80_H__
-+#define __DAL_AUX_ENGINE_DCE80_H__
-+
-+struct aux_engine_dce80 {
-+ 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_dce80_create_arg {
-+ uint32_t engine_id;
-+ uint32_t timeout_period;
-+ struct dc_context *ctx;
-+};
-+
-+struct aux_engine *dal_aux_engine_dce80_create(
-+ const struct aux_engine_dce80_create_arg *arg);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_hw_engine_dce80.c b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_hw_engine_dce80.c
-new file mode 100644
-index 0000000..3d61963
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_hw_engine_dce80.c
-@@ -0,0 +1,901 @@
-+/*
-+ * 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 "dm_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"
-+#include "../i2c_generic_hw_engine.h"
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "i2c_hw_engine_dce80.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_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 'struct i2c_hw_engine *'
-+ * to 'struct i2c_hw_engine_dce80 *'
-+ */
-+#define FROM_I2C_HW_ENGINE(ptr) \
-+ container_of((ptr), struct i2c_hw_engine_dce80, base)
-+
-+/*
-+ * @brief
-+ * Cast pointer to 'struct i2c_engine *'
-+ * to pointer to 'struct i2c_hw_engine_dce80 *'
-+ */
-+#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_dce80 *'
-+ */
-+#define FROM_ENGINE(ptr) \
-+ FROM_I2C_ENGINE(container_of((ptr), struct i2c_engine, base))
-+
-+static void disable_i2c_hw_engine(
-+ struct i2c_hw_engine_dce80 *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 = dm_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DC_I2C_DDC1_SETUP,
-+ DC_I2C_DDC1_ENABLE);
-+
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+static void release_engine(
-+ struct engine *engine)
-+{
-+ struct i2c_hw_engine_dce80 *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 = dm_read_reg(engine->ctx, mmDC_I2C_ARBITRATION);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_ARBITRATION,
-+ DC_I2C_SW_DONE_USING_I2C_REG);
-+
-+ dm_write_reg(engine->ctx, mmDC_I2C_ARBITRATION, value);
-+ }
-+
-+ /* Reset HW engine */
-+ {
-+ uint32_t i2c_sw_status = 0;
-+
-+ value = dm_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 = dm_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);
-+
-+ dm_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_dce80 *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 void destruct(
-+ struct i2c_hw_engine_dce80 *engine)
-+{
-+ dal_i2c_hw_engine_destruct(&engine->base);
-+}
-+
-+static void destroy(
-+ struct i2c_engine **i2c_engine)
-+{
-+ struct i2c_hw_engine_dce80 *engine = FROM_I2C_ENGINE(*i2c_engine);
-+
-+ destruct(engine);
-+
-+ dm_free((*i2c_engine)->base.ctx, engine);
-+
-+ *i2c_engine = NULL;
-+}
-+
-+static bool setup_engine(
-+ struct i2c_engine *i2c_engine)
-+{
-+ uint32_t value = 0;
-+ struct i2c_hw_engine_dce80 *engine = FROM_I2C_ENGINE(i2c_engine);
-+
-+ /* Program pin select */
-+ {
-+ const uint32_t addr = mmDC_I2C_CONTROL;
-+
-+ value = dm_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);
-+
-+
-+ dm_write_reg(i2c_engine->base.ctx, addr, value);
-+ }
-+
-+ /* Program time limit */
-+ {
-+ const uint32_t addr = engine->addr.DC_I2C_DDCX_SETUP;
-+
-+ value = dm_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);
-+
-+ dm_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 = dm_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);
-+
-+ dm_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_dce80 *engine = FROM_I2C_ENGINE(i2c_engine);
-+
-+ const uint32_t addr = engine->addr.DC_I2C_DDCX_SPEED;
-+
-+ uint32_t pre_scale = 0;
-+
-+ uint32_t value = dm_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_dce80 *engine = FROM_I2C_ENGINE(i2c_engine);
-+
-+ if (speed) {
-+ const uint32_t addr = engine->addr.DC_I2C_DDCX_SPEED;
-+
-+ uint32_t value = dm_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);
-+
-+ dm_write_reg(i2c_engine->base.ctx, addr, value);
-+ }
-+}
-+
-+static inline void reset_hw_engine(struct engine *engine)
-+{
-+ uint32_t value = dm_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);
-+
-+ dm_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 = dm_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 = dm_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_dce80 *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 = dm_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);
-+
-+ dm_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);
-+ }
-+
-+ dm_write_reg(ctx, mmDC_I2C_DATA, value);
-+
-+ 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);
-+
-+ dm_write_reg(ctx, mmDC_I2C_DATA, value);
-+ --length;
-+ }
-+ }
-+ }
-+
-+ ++engine->transaction_count;
-+ engine->buffer_used_bytes += length + 1;
-+
-+ return last_transaction;
-+}
-+
-+static void execute_transaction(
-+ struct i2c_hw_engine_dce80 *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 = dm_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);
-+
-+ dm_write_reg(ctx, addr, value);
-+ }
-+
-+ {
-+ const uint32_t addr = mmDC_I2C_CONTROL;
-+
-+ value = dm_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);
-+
-+ dm_write_reg(ctx, addr, value);
-+ }
-+
-+ /* start I2C transfer */
-+ {
-+ const uint32_t addr = mmDC_I2C_CONTROL;
-+
-+ value = dm_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_I2C_CONTROL,
-+ DC_I2C_GO);
-+
-+ dm_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;
-+
-+ uint32_t value = 0;
-+
-+ /*set index*/
-+ set_reg_field_value(
-+ value,
-+ length - 1,
-+ 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);
-+
-+ dm_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 = dm_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 = dm_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;
-+}
-+
-+/*
-+ * @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_dce80 *engine,
-+ const struct i2c_hw_engine_dce80_create_arg *arg)
-+{
-+ 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->base, arg->ctx))
-+ return false;
-+
-+ engine->base.base.base.funcs = &engine_funcs;
-+ engine->base.base.funcs = &i2c_engine_funcs;
-+ engine->base.funcs = &i2c_hw_engine_funcs;
-+ engine->base.default_speed = arg->default_speed;
-+ engine->addr.DC_I2C_DDCX_SETUP =
-+ mmDC_I2C_DDC1_SETUP + ddc_setup_offset[arg->engine_id];
-+ engine->addr.DC_I2C_DDCX_SPEED =
-+ mmDC_I2C_DDC1_SPEED + ddc_speed_offset[arg->engine_id];
-+
-+ engine->engine_id = arg->engine_id;
-+ engine->reference_frequency = arg->reference_frequency;
-+ engine->buffer_used_bytes = 0;
-+ engine->transaction_count = 0;
-+ engine->engine_keep_power_up_count = 1;
-+
-+ return true;
-+}
-+
-+struct i2c_engine *dal_i2c_hw_engine_dce80_create(
-+ const struct i2c_hw_engine_dce80_create_arg *arg)
-+{
-+ struct i2c_hw_engine_dce80 *engine;
-+
-+ if (!arg) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ engine = dm_alloc(arg->ctx, sizeof(struct i2c_hw_engine_dce80));
-+
-+ if (!engine) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ if (construct(engine, arg))
-+ return &engine->base.base;
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ dm_free(arg->ctx, engine);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_hw_engine_dce80.h b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_hw_engine_dce80.h
-new file mode 100644
-index 0000000..5c6116f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_hw_engine_dce80.h
-@@ -0,0 +1,54 @@
-+/*
-+ * 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_DCE80_H__
-+#define __DAL_I2C_HW_ENGINE_DCE80_H__
-+
-+struct i2c_hw_engine_dce80 {
-+ 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 pending transactions (before GO) */
-+ uint32_t transaction_count;
-+ uint32_t engine_keep_power_up_count;
-+};
-+
-+struct i2c_hw_engine_dce80_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_dce80_create(
-+ const struct i2c_hw_engine_dce80_create_arg *arg);
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_sw_engine_dce80.c b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_sw_engine_dce80.c
-new file mode 100644
-index 0000000..e5135c5
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_sw_engine_dce80.c
-@@ -0,0 +1,187 @@
-+/*
-+ * 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 "dm_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_dce80.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+#include "dce/dce_8_0_d.h"
-+#include "dce/dce_8_0_sh_mask.h"
-+
-+/*
-+ * This unit
-+ */
-+
-+static const uint32_t ddc_hw_status_addr[] = {
-+ mmDC_I2C_DDC1_HW_STATUS,
-+ mmDC_I2C_DDC2_HW_STATUS,
-+ mmDC_I2C_DDC3_HW_STATUS,
-+ mmDC_I2C_DDC4_HW_STATUS,
-+ mmDC_I2C_DDC5_HW_STATUS,
-+ mmDC_I2C_DDC6_HW_STATUS,
-+ mmDC_I2C_DDCVGA_HW_STATUS
-+};
-+
-+
-+/*
-+ * @brief
-+ * Cast 'struct i2c_sw_engine *'
-+ * to 'struct i2c_sw_engine_dce80 *'
-+ */
-+#define FROM_I2C_SW_ENGINE(ptr) \
-+ container_of((ptr), struct i2c_sw_engine_dce80, 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_dce80 *engine)
-+{
-+ dal_i2c_sw_engine_destruct(&engine->base);
-+}
-+
-+static void destroy(
-+ struct i2c_engine **engine)
-+{
-+ struct i2c_sw_engine_dce80 *sw_engine = FROM_I2C_ENGINE(*engine);
-+
-+ destruct(sw_engine);
-+
-+ dm_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_dce80 *engine,
-+ const struct i2c_sw_engine_dce80_create_arg *arg)
-+{
-+ struct i2c_sw_engine_create_arg arg_base;
-+
-+ arg_base.ctx = arg->ctx;
-+ arg_base.default_speed = arg->default_speed;
-+
-+ if (!dal_i2c_sw_engine_construct(&engine->base, &arg_base)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ engine->base.base.base.funcs = &engine_funcs;
-+ engine->base.base.funcs = &i2c_engine_funcs;
-+ engine->base.default_speed = arg->default_speed;
-+ engine->engine_id = arg->engine_id;
-+
-+ return true;
-+}
-+
-+struct i2c_engine *dal_i2c_sw_engine_dce80_create(
-+ const struct i2c_sw_engine_dce80_create_arg *arg)
-+{
-+ struct i2c_sw_engine_dce80 *engine;
-+
-+ if (!arg) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ engine = dm_alloc(arg->ctx, sizeof(struct i2c_sw_engine_dce80));
-+
-+ if (!engine) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ if (construct(engine, arg))
-+ return &engine->base.base;
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ dm_free(arg->ctx, engine);
-+
-+ return NULL;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_sw_engine_dce80.h b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_sw_engine_dce80.h
-new file mode 100644
-index 0000000..26355c0
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2c_sw_engine_dce80.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_DCE80_H__
-+#define __DAL_I2C_SW_ENGINE_DCE80_H__
-+
-+struct i2c_sw_engine_dce80 {
-+ struct i2c_sw_engine base;
-+ uint32_t engine_id;
-+};
-+
-+struct i2c_sw_engine_dce80_create_arg {
-+ uint32_t engine_id;
-+ uint32_t default_speed;
-+ struct dc_context *ctx;
-+};
-+
-+struct i2c_engine *dal_i2c_sw_engine_dce80_create(
-+ const struct i2c_sw_engine_dce80_create_arg *arg);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2caux_dce80.c b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2caux_dce80.c
-new file mode 100644
-index 0000000..4abf488
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2caux_dce80.c
-@@ -0,0 +1,264 @@
-+/*
-+ * 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 "dm_services.h"
-+
-+/*
-+ * Pre-requisites: headers required by header of this unit
-+ */
-+#include "include/i2caux_interface.h"
-+#include "../i2caux.h"
-+
-+/*
-+ * Header of this unit
-+ */
-+
-+#include "i2caux_dce80.h"
-+
-+/*
-+ * Post-requisites: headers required by this unit
-+ */
-+
-+#include "../engine.h"
-+#include "../i2c_engine.h"
-+#include "../i2c_sw_engine.h"
-+#include "i2c_sw_engine_dce80.h"
-+#include "../i2c_hw_engine.h"
-+#include "i2c_hw_engine_dce80.h"
-+#include "../i2c_generic_hw_engine.h"
-+#include "../aux_engine.h"
-+#include "aux_engine_dce80.h"
-+
-+
-+/*
-+ * This unit
-+ */
-+
-+#define FROM_I2C_AUX(ptr) \
-+ container_of((ptr), struct i2caux_dce80, base)
-+
-+static void destruct(
-+ struct i2caux_dce80 *i2caux_dce80)
-+{
-+ dal_i2caux_destruct(&i2caux_dce80->base);
-+}
-+
-+static void destroy(
-+ struct i2caux **i2c_engine)
-+{
-+ struct i2caux_dce80 *i2caux_dce80 = FROM_I2C_AUX(*i2c_engine);
-+
-+ destruct(i2caux_dce80);
-+
-+ dm_free((*i2c_engine)->ctx, i2caux_dce80);
-+
-+ *i2c_engine = NULL;
-+}
-+
-+static struct i2c_engine *acquire_i2c_hw_engine(
-+ struct i2caux *i2caux,
-+ struct ddc *ddc)
-+{
-+ struct i2caux_dce80 *i2caux_dce80 = FROM_I2C_AUX(i2caux);
-+
-+ struct i2c_engine *engine = NULL;
-+ bool non_generic;
-+
-+ 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) {
-+ non_generic = true;
-+ engine = i2caux->i2c_hw_engines[line];
-+ }
-+ }
-+
-+ if (!engine) {
-+ non_generic = false;
-+ engine = i2caux->i2c_generic_hw_engine;
-+ }
-+
-+ if (!engine)
-+ return NULL;
-+
-+ if (non_generic) {
-+ if (!i2caux_dce80->i2c_hw_buffer_in_use &&
-+ engine->base.funcs->acquire(&engine->base, ddc)) {
-+ i2caux_dce80->i2c_hw_buffer_in_use = true;
-+ return engine;
-+ }
-+ } else {
-+ if (engine->base.funcs->acquire(&engine->base, ddc))
-+ return engine;
-+ }
-+
-+ return NULL;
-+}
-+
-+static void release_engine(
-+ struct i2caux *i2caux,
-+ struct engine *engine)
-+{
-+ if (engine->funcs->get_engine_type(engine) ==
-+ I2CAUX_ENGINE_TYPE_I2C_DDC_HW)
-+ FROM_I2C_AUX(i2caux)->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,
-+ GPIO_DDC_LINE_DDC4,
-+ GPIO_DDC_LINE_DDC5,
-+ GPIO_DDC_LINE_DDC6,
-+ GPIO_DDC_LINE_DDC_VGA
-+};
-+
-+static const enum gpio_ddc_line hw_aux_lines[] = {
-+ GPIO_DDC_LINE_DDC1,
-+ GPIO_DDC_LINE_DDC2,
-+ GPIO_DDC_LINE_DDC3,
-+ GPIO_DDC_LINE_DDC4,
-+ GPIO_DDC_LINE_DDC5,
-+ GPIO_DDC_LINE_DDC6
-+};
-+
-+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_dce80 *i2caux_dce80,
-+ struct adapter_service *as,
-+ struct dc_context *ctx)
-+{
-+ /* Entire family have I2C engine reference clock frequency
-+ * changed from XTALIN (27) to XTALIN/2 (13.5) */
-+
-+ struct i2caux *base = &i2caux_dce80->base;
-+
-+ uint32_t reference_frequency =
-+ dal_i2caux_get_reference_clock(as) >> 1;
-+
-+ bool use_i2c_sw_engine = dal_adapter_service_is_feature_supported(
-+ FEATURE_RESTORE_USAGE_I2C_SW_ENGINE);
-+
-+ uint32_t i;
-+
-+ if (!dal_i2caux_construct(base, as, ctx)) {
-+ BREAK_TO_DEBUGGER();
-+ return false;
-+ }
-+
-+ i2caux_dce80->base.funcs = &i2caux_funcs;
-+ i2caux_dce80->i2c_hw_buffer_in_use = false;
-+
-+ /* Create I2C HW engines (HW + SW pairs)
-+ * for all lines which has assisted HW DDC
-+ * 'i' (loop counter) used as DDC/AUX engine_id */
-+
-+ i = 0;
-+
-+ do {
-+ enum gpio_ddc_line line_id = hw_ddc_lines[i];
-+
-+ struct i2c_hw_engine_dce80_create_arg hw_arg;
-+
-+ if (use_i2c_sw_engine) {
-+ struct i2c_sw_engine_dce80_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_dce80_create(&sw_arg);
-+ }
-+
-+ hw_arg.engine_id = i;
-+ hw_arg.reference_frequency = reference_frequency;
-+ hw_arg.default_speed = base->default_i2c_hw_speed;
-+ hw_arg.ctx = ctx;
-+
-+ base->i2c_hw_engines[line_id] =
-+ dal_i2c_hw_engine_dce80_create(&hw_arg);
-+
-+ ++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_dce80_create_arg arg;
-+
-+ arg.engine_id = i;
-+ arg.timeout_period = base->aux_timeout_period;
-+ arg.ctx = ctx;
-+
-+ base->aux_engines[line_id] =
-+ dal_aux_engine_dce80_create(&arg);
-+
-+ ++i;
-+ } while (i < ARRAY_SIZE(hw_aux_lines));
-+
-+ /* TODO Generic I2C SW and HW */
-+
-+ return true;
-+}
-+
-+struct i2caux *dal_i2caux_dce80_create(
-+ struct adapter_service *as,
-+ struct dc_context *ctx)
-+{
-+ struct i2caux_dce80 *i2caux_dce80 =
-+ dm_alloc(ctx, sizeof(struct i2caux_dce80));
-+
-+ if (!i2caux_dce80) {
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+ }
-+
-+ if (construct(i2caux_dce80, as, ctx))
-+ return &i2caux_dce80->base;
-+
-+ BREAK_TO_DEBUGGER();
-+
-+ dm_free(ctx, i2caux_dce80);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2caux_dce80.h b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2caux_dce80.h
-new file mode 100644
-index 0000000..85417a8
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/dce80/i2caux_dce80.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_DCE80_H__
-+#define __DAL_I2C_AUX_DCE80_H__
-+
-+struct i2caux_dce80 {
-+ struct i2caux base;
-+ /* indicate the I2C HW circular buffer is in use */
-+ bool i2c_hw_buffer_in_use;
-+};
-+
-+struct i2caux *dal_i2caux_dce80_create(
-+ struct adapter_service *as,
-+ struct dc_context *ctx);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c b/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c
-index 4c2f2cb..47e7922 100644
---- a/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c
-@@ -48,6 +48,10 @@
- * This unit
- */
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+#include "dce80/i2caux_dce80.h"
-+#endif
-+
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0) || defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- #include "dce110/i2caux_dce110.h"
- #endif
-@@ -79,6 +83,10 @@ struct i2caux *dal_i2caux_create(
- }
-
- switch (dce_version) {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ case DCE_VERSION_8_0:
-+ return dal_i2caux_dce80_create(as, ctx);
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- case DCE_VERSION_10_0:
-diff --git a/drivers/gpu/drm/amd/dal/dc/irq/irq_service.c b/drivers/gpu/drm/amd/dal/dc/irq/irq_service.c
-index 1372331..3e2f232 100644
---- a/drivers/gpu/drm/amd/dal/dc/irq/irq_service.c
-+++ b/drivers/gpu/drm/amd/dal/dc/irq/irq_service.c
-@@ -32,6 +32,13 @@
- #include "dce110/irq_service_dce110.h"
- #endif
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ /*
-+ * TODO: implement DCE8.x IRQ service
-+ */
-+#include "dce110/irq_service_dce110.h"
-+#endif
-+
- #include "irq_service.h"
-
- bool dal_irq_service_construct(
-@@ -50,6 +57,10 @@ struct irq_service *dal_irq_service_create(
- struct irq_service_init_data *init_data)
- {
- switch (version) {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ case DCE_VERSION_8_0:
-+ return dal_irq_service_dce110_create(init_data);
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- case DCE_VERSION_10_0:
- return dal_irq_service_dce110_create(init_data);
-diff --git a/drivers/gpu/drm/amd/dal/include/dal_types.h b/drivers/gpu/drm/amd/dal/include/dal_types.h
-index 3739776..8fdde70 100644
---- a/drivers/gpu/drm/amd/dal/include/dal_types.h
-+++ b/drivers/gpu/drm/amd/dal/include/dal_types.h
-@@ -34,6 +34,9 @@ struct dc_bios;
-
- enum dce_version {
- DCE_VERSION_UNKNOWN = (-1),
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ DCE_VERSION_8_0,
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- DCE_VERSION_10_0,
- #endif
-diff --git a/drivers/gpu/drm/amd/dal/include/display_clock_interface.h b/drivers/gpu/drm/amd/dal/include/display_clock_interface.h
-index 009b583..a621930 100644
---- a/drivers/gpu/drm/amd/dal/include/display_clock_interface.h
-+++ b/drivers/gpu/drm/amd/dal/include/display_clock_interface.h
-@@ -143,6 +143,12 @@ struct display_clock *dal_display_clock_dce80_create(
- struct adapter_service *as);
- #endif
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+struct display_clock *dal_display_clock_dce80_create(
-+ struct dc_context *ctx,
-+ struct adapter_service *as);
-+#endif
-+
- void dal_display_clock_destroy(struct display_clock **to_destroy);
- bool dal_display_clock_validate(
- struct display_clock *disp_clk,
---
-2.7.4
-