aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0956-drm-amd-dal-add-core-support-for-Polaris-family-v2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0956-drm-amd-dal-add-core-support-for-Polaris-family-v2.patch')
-rw-r--r--common/recipes-kernel/linux/files/0956-drm-amd-dal-add-core-support-for-Polaris-family-v2.patch9820
1 files changed, 0 insertions, 9820 deletions
diff --git a/common/recipes-kernel/linux/files/0956-drm-amd-dal-add-core-support-for-Polaris-family-v2.patch b/common/recipes-kernel/linux/files/0956-drm-amd-dal-add-core-support-for-Polaris-family-v2.patch
deleted file mode 100644
index 6143ca86..00000000
--- a/common/recipes-kernel/linux/files/0956-drm-amd-dal-add-core-support-for-Polaris-family-v2.patch
+++ /dev/null
@@ -1,9820 +0,0 @@
-From bc3e400b9b554d0e8448d89c7a721f887b612dfc Mon Sep 17 00:00:00 2001
-From: Alex Deucher <alexander.deucher@amd.com>
-Date: Tue, 15 Mar 2016 10:53:48 -0400
-Subject: [PATCH 0956/1110] drm/amd/dal: add core support for Polaris family
- (v2)
-
-This adds core dc support for polaris 10 and 11.
-
-v2: add missing files
-
-Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
----
- drivers/gpu/drm/amd/dal/dc/Makefile | 4 +
- drivers/gpu/drm/amd/dal/dc/adapter/Makefile | 4 +
- .../gpu/drm/amd/dal/dc/adapter/adapter_service.c | 12 +
- .../adapter/dce112/hw_ctx_adapter_service_dce112.c | 302 +++
- .../adapter/dce112/hw_ctx_adapter_service_dce112.h | 39 +
- .../gpu/drm/amd/dal/dc/asic_capability/Makefile | 9 +
- .../amd/dal/dc/asic_capability/asic_capability.c | 15 +-
- .../dc/asic_capability/polaris10_asic_capability.c | 146 ++
- .../dc/asic_capability/polaris10_asic_capability.h | 36 +
- drivers/gpu/drm/amd/dal/dc/audio/Makefile | 8 +
- drivers/gpu/drm/amd/dal/dc/audio/audio_base.c | 9 +
- .../gpu/drm/amd/dal/dc/audio/dce112/audio_dce112.c | 451 +++++
- .../gpu/drm/amd/dal/dc/audio/dce112/audio_dce112.h | 40 +
- .../amd/dal/dc/audio/dce112/hw_ctx_audio_dce112.c | 1923 ++++++++++++++++++++
- .../amd/dal/dc/audio/dce112/hw_ctx_audio_dce112.h | 47 +
- drivers/gpu/drm/amd/dal/dc/bios/Makefile | 9 +
- .../gpu/drm/amd/dal/dc/bios/bios_parser_helper.c | 6 +
- .../gpu/drm/amd/dal/dc/bios/bios_parser_helper.h | 4 +
- drivers/gpu/drm/amd/dal/dc/bios/command_table.c | 78 +-
- .../gpu/drm/amd/dal/dc/bios/command_table_helper.c | 6 +
- .../gpu/drm/amd/dal/dc/bios/command_table_helper.h | 3 +
- .../dal/dc/bios/dce112/bios_parser_helper_dce112.c | 480 +++++
- .../dal/dc/bios/dce112/bios_parser_helper_dce112.h | 34 +
- .../dc/bios/dce112/command_table_helper_dce112.c | 417 +++++
- .../dc/bios/dce112/command_table_helper_dce112.h | 34 +
- drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c | 206 +++
- drivers/gpu/drm/amd/dal/dc/core/dc_hw_sequencer.c | 7 +
- drivers/gpu/drm/amd/dal/dc/core/dc_resource.c | 22 +-
- .../drm/amd/dal/dc/dce110/dce110_hw_sequencer.c | 1 +
- .../amd/dal/dc/dce110/dce110_timing_generator.c | 2 +-
- drivers/gpu/drm/amd/dal/dc/dce112/Makefile | 10 +
- .../drm/amd/dal/dc/dce112/dce112_clock_source.c | 266 +++
- .../drm/amd/dal/dc/dce112/dce112_clock_source.h | 52 +
- .../gpu/drm/amd/dal/dc/dce112/dce112_compressor.c | 883 +++++++++
- .../gpu/drm/amd/dal/dc/dce112/dce112_compressor.h | 84 +
- .../drm/amd/dal/dc/dce112/dce112_hw_sequencer.c | 178 ++
- .../drm/amd/dal/dc/dce112/dce112_hw_sequencer.h | 36 +
- .../drm/amd/dal/dc/dce112/dce112_link_encoder.c | 116 ++
- .../drm/amd/dal/dc/dce112/dce112_link_encoder.h | 41 +
- .../gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c | 455 +++++
- .../gpu/drm/amd/dal/dc/dce112/dce112_mem_input.h | 38 +
- .../gpu/drm/amd/dal/dc/dce112/dce112_resource.c | 1404 ++++++++++++++
- .../gpu/drm/amd/dal/dc/dce112/dce112_resource.h | 42 +
- drivers/gpu/drm/amd/dal/dc/dm_services_types.h | 5 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c | 3 +
- drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c | 3 +
- drivers/gpu/drm/amd/dal/dc/gpu/Makefile | 8 +
- .../amd/dal/dc/gpu/dce112/dc_clock_gating_dce112.c | 89 +
- .../amd/dal/dc/gpu/dce112/dc_clock_gating_dce112.h | 33 +
- .../amd/dal/dc/gpu/dce112/display_clock_dce112.c | 964 ++++++++++
- .../amd/dal/dc/gpu/dce112/display_clock_dce112.h | 54 +
- drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c | 5 +-
- drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h | 4 +-
- drivers/gpu/drm/amd/dal/dc/irq/irq_service.c | 4 +
- drivers/gpu/drm/amd/dal/include/dal_asic_id.h | 14 +
- drivers/gpu/drm/amd/dal/include/dal_types.h | 3 +
- .../drm/amd/dal/include/display_clock_interface.h | 6 +
- 57 files changed, 9146 insertions(+), 8 deletions(-)
- create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/dce112/hw_ctx_adapter_service_dce112.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/dce112/hw_ctx_adapter_service_dce112.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/asic_capability/polaris10_asic_capability.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/asic_capability/polaris10_asic_capability.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/dce112/audio_dce112.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/dce112/audio_dce112.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/dce112/hw_ctx_audio_dce112.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/audio/dce112/hw_ctx_audio_dce112.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/dce112/bios_parser_helper_dce112.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/dce112/bios_parser_helper_dce112.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/dce112/command_table_helper_dce112.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/bios/dce112/command_table_helper_dce112.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/Makefile
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_compressor.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_compressor.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_hw_sequencer.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_hw_sequencer.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_link_encoder.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_link_encoder.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce112/dc_clock_gating_dce112.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce112/dc_clock_gating_dce112.h
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce112/display_clock_dce112.c
- create mode 100644 drivers/gpu/drm/amd/dal/dc/gpu/dce112/display_clock_dce112.h
-
-diff --git a/drivers/gpu/drm/amd/dal/dc/Makefile b/drivers/gpu/drm/amd/dal/dc/Makefile
-index 5112ec9..a718674 100644
---- a/drivers/gpu/drm/amd/dal/dc/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/Makefile
-@@ -5,6 +5,10 @@
- DC_LIBS = adapter asic_capability audio basics bios calcs \
- gpio gpu i2caux irq virtual
-
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_2
-+DC_LIBS += dce112
-+endif
-+
- ifdef CONFIG_DRM_AMD_DAL_DCE11_0
- DC_LIBS += dce110
- endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/Makefile b/drivers/gpu/drm/amd/dal/dc/adapter/Makefile
-index db1f0e8..370323e 100644
---- a/drivers/gpu/drm/amd/dal/dc/adapter/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/Makefile
-@@ -25,6 +25,10 @@ ifdef CONFIG_DRM_AMD_DAL_DCE11_0
- AMD_DAL_FILES += $(AMDDALPATH)/dc/adapter/dce110/hw_ctx_adapter_service_dce110.o
- endif
-
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_2
-+AMD_DAL_FILES += $(AMDDALPATH)/dc/adapter/dce112/hw_ctx_adapter_service_dce112.o
-+endif
-+
- ###############################################################################
- # FPGA Diagnositcs
- ###############################################################################
-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 f7aea01..308d456 100644
---- a/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c
-@@ -49,6 +49,10 @@
- #include "dce110/hw_ctx_adapter_service_dce110.h"
- #endif
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+#include "dce112/hw_ctx_adapter_service_dce112.h"
-+#endif
-+
- #include "diagnostics/hw_ctx_adapter_service_diag.h"
-
- /*
-@@ -664,6 +668,10 @@ static struct hw_ctx_adapter_service *create_hw_ctx(
- case DCE_VERSION_11_0:
- return dal_adapter_service_create_hw_ctx_dce110(ctx);
- #endif
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ case DCE_VERSION_11_2:
-+ return dal_adapter_service_create_hw_ctx_dce112(ctx);
-+#endif
- default:
- ASSERT_CRITICAL(false);
- return NULL;
-@@ -907,6 +915,10 @@ enum dce_version dal_adapter_service_get_dce_version(
- case 0x110:
- return DCE_VERSION_11_0;
- #endif
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ case 0x112:
-+ return DCE_VERSION_11_2;
-+#endif
- default:
- ASSERT_CRITICAL(false);
- return DCE_VERSION_UNKNOWN;
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/dce112/hw_ctx_adapter_service_dce112.c b/drivers/gpu/drm/amd/dal/dc/adapter/dce112/hw_ctx_adapter_service_dce112.c
-new file mode 100644
-index 0000000..f438998
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/dce112/hw_ctx_adapter_service_dce112.c
-@@ -0,0 +1,302 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 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 "../hw_ctx_adapter_service.h"
-+
-+#include "hw_ctx_adapter_service_dce112.h"
-+
-+#include "include/logger_interface.h"
-+#include "include/grph_object_id.h"
-+
-+#include "dce/dce_11_2_d.h"
-+#include "dce/dce_11_2_sh_mask.h"
-+
-+#ifndef mmCC_DC_HDMI_STRAPS
-+#define mmCC_DC_HDMI_STRAPS 0x4819
-+#define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
-+#define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
-+#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
-+#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
-+#endif
-+
-+static const struct graphics_object_id invalid_go = {
-+ 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN, 0
-+};
-+
-+/* Macro */
-+#define AUDIO_STRAPS_HDMI_ENABLE 0x2
-+
-+#define FROM_HW_CTX(ptr) \
-+ container_of((ptr), struct hw_ctx_adapter_service_dce112, base)
-+
-+static const uint32_t audio_index_reg_offset[] = {
-+ /*CZ has 3 DIGs but 4 audio endpoints*/
-+ mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_INDEX
-+};
-+
-+static const uint32_t audio_data_reg_offset[] = {
-+ mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA,
-+ mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_DATA,
-+ mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_DATA,
-+ mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_DATA,
-+};
-+
-+enum {
-+ MAX_NUMBER_OF_AUDIO_PINS = 4
-+};
-+
-+static void destruct(
-+ struct hw_ctx_adapter_service_dce112 *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_dce112 *hw_ctx =
-+ FROM_HW_CTX(ptr);
-+
-+ destruct(hw_ctx);
-+
-+ dm_free(hw_ctx);
-+}
-+
-+/*
-+ * enum_audio_object
-+ *
-+ * @brief enumerate audio object
-+ *
-+ * @param
-+ * const struct hw_ctx_adapter_service *hw_ctx - [in] provides num of endpoints
-+ * uint32_t index - [in] audio index
-+ *
-+ * @return
-+ * grphic object id
-+ */
-+static struct graphics_object_id enum_audio_object(
-+ const struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t index)
-+{
-+ uint32_t number_of_connected_audio_endpoints =
-+ FROM_HW_CTX(hw_ctx)->number_of_connected_audio_endpoints;
-+
-+ if (index >= number_of_connected_audio_endpoints ||
-+ number_of_connected_audio_endpoints == 0)
-+ return invalid_go;
-+ else
-+ return dal_graphics_object_id_init(
-+ AUDIO_ID_INTERNAL_AZALIA,
-+ (enum object_enum_id)(index + 1),
-+ OBJECT_TYPE_AUDIO);
-+}
-+
-+static uint32_t get_number_of_connected_audio_endpoints_multistream(
-+ struct dc_context *ctx)
-+{
-+ uint32_t num_connected_audio_endpoints = 0;
-+ uint32_t i;
-+ uint32_t default_config =
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT;
-+
-+ /* find the total number of streams available via the
-+ * AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT
-+ * registers (one for each pin) starting from pin 1
-+ * up to the max number of audio pins.
-+ * We stop on the first pin where
-+ * PORT_CONNECTIVITY == 1 (as instructed by HW team).
-+ */
-+ for (i = 0; i < MAX_NUMBER_OF_AUDIO_PINS; i++) {
-+ uint32_t value = 0;
-+
-+ set_reg_field_value(value,
-+ default_config,
-+ AZALIA_F0_CODEC_ENDPOINT_INDEX,
-+ AZALIA_ENDPOINT_REG_INDEX);
-+
-+ 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;
-+
-+}
-+
-+/*
-+ * get_number_of_connected_audio_endpoints
-+ */
-+static uint32_t get_number_of_connected_audio_endpoints(
-+ struct hw_ctx_adapter_service *hw_ctx)
-+{
-+ uint32_t addr = mmCC_DC_HDMI_STRAPS;
-+ uint32_t value = 0;
-+ uint32_t field = 0;
-+
-+ if (hw_ctx->cached_audio_straps == AUDIO_STRAPS_NOT_ALLOWED)
-+ /* audio straps indicate no audio supported */
-+ return 0;
-+
-+ value = 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->ctx);
-+
-+ /* unexpected value */
-+ ASSERT_CRITICAL(false);
-+ return field;
-+}
-+
-+/*
-+ * power_up
-+ *
-+ * @brief
-+ * Determine and cache audio support from register.
-+ *
-+ * @param
-+ * struct hw_ctx_adapter_service *hw_ctx - [in] adapter service hw context
-+ *
-+ * @return
-+ * true if succeed, false otherwise
-+ */
-+static bool power_up(
-+ struct hw_ctx_adapter_service *hw_ctx)
-+{
-+ struct hw_ctx_adapter_service_dce112 *hw_ctx_dce11 =
-+ FROM_HW_CTX(hw_ctx);
-+ /* Allow DP audio all the time
-+ * without additional pinstrap check on Fusion */
-+
-+ {
-+ uint32_t value = 0;
-+ uint32_t field = 0;
-+
-+ value = 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);
-+
-+ if (field & AUDIO_STRAPS_HDMI_ENABLE)
-+ hw_ctx->cached_audio_straps =
-+ AUDIO_STRAPS_DP_HDMI_AUDIO_ON_DONGLE;
-+ else
-+ hw_ctx->cached_audio_straps =
-+ AUDIO_STRAPS_DP_AUDIO_ALLOWED;
-+ }
-+
-+ }
-+
-+ /* get the number of connected audio endpoints */
-+ hw_ctx_dce11->number_of_connected_audio_endpoints =
-+ get_number_of_connected_audio_endpoints(hw_ctx);
-+
-+ return true;
-+}
-+
-+static void update_audio_connectivity(
-+ struct hw_ctx_adapter_service *hw_ctx,
-+ uint32_t number_of_audio_capable_display_path,
-+ uint32_t number_of_controllers)
-+{
-+ /* this one should be empty on DCE112 */
-+}
-+
-+static const struct hw_ctx_adapter_service_funcs funcs = {
-+ .destroy = destroy,
-+ .power_up = power_up,
-+ .enum_fake_path_resource = NULL,
-+ .enum_stereo_sync_object = NULL,
-+ .enum_sync_output_object = NULL,
-+ .enum_audio_object = enum_audio_object,
-+ .update_audio_connectivity = update_audio_connectivity
-+};
-+
-+static bool construct(
-+ struct hw_ctx_adapter_service_dce112 *hw_ctx,
-+ struct dc_context *ctx)
-+{
-+ if (!dal_adapter_service_construct_hw_ctx(&hw_ctx->base, ctx)) {
-+ ASSERT_CRITICAL(false);
-+ return false;
-+ }
-+
-+ hw_ctx->base.funcs = &funcs;
-+ hw_ctx->number_of_connected_audio_endpoints = 0;
-+
-+ return true;
-+}
-+
-+struct hw_ctx_adapter_service *
-+ dal_adapter_service_create_hw_ctx_dce112(
-+ struct dc_context *ctx)
-+{
-+ struct hw_ctx_adapter_service_dce112 *hw_ctx =
-+ dm_alloc(sizeof(struct hw_ctx_adapter_service_dce112));
-+
-+ if (!hw_ctx) {
-+ ASSERT_CRITICAL(false);
-+ return NULL;
-+ }
-+
-+ if (construct(hw_ctx, ctx))
-+ return &hw_ctx->base;
-+
-+ ASSERT_CRITICAL(false);
-+
-+ dm_free(hw_ctx);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/dce112/hw_ctx_adapter_service_dce112.h b/drivers/gpu/drm/amd/dal/dc/adapter/dce112/hw_ctx_adapter_service_dce112.h
-new file mode 100644
-index 0000000..bc60030
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/adapter/dce112/hw_ctx_adapter_service_dce112.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_HW_CTX_ADAPTER_SERVICE_DCE112_H__
-+#define __DAL_HW_CTX_ADAPTER_SERVICE_DCE112_H__
-+
-+struct hw_ctx_adapter_service_dce112 {
-+ struct hw_ctx_adapter_service base;
-+ uint32_t number_of_connected_audio_endpoints;
-+};
-+
-+struct hw_ctx_adapter_service *
-+ dal_adapter_service_create_hw_ctx_dce112(
-+ struct dc_context *ctx);
-+
-+#endif /* __DAL_HW_CTX_ADAPTER_SERVICE_DCE112_H__ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/asic_capability/Makefile b/drivers/gpu/drm/amd/dal/dc/asic_capability/Makefile
-index b243542..e80de2a 100644
---- a/drivers/gpu/drm/amd/dal/dc/asic_capability/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/asic_capability/Makefile
-@@ -46,3 +46,12 @@ AMD_DAL_ASIC_CAPABILITY_DCE11 = \
-
- AMD_DAL_FILES += $(AMD_DAL_ASIC_CAPABILITY_DCE11)
- endif
-+
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_2
-+ASIC_CAPABILITY_DCE112 = polaris10_asic_capability.o
-+
-+AMD_DAL_ASIC_CAPABILITY_DCE112 = \
-+ $(addprefix $(AMDDALPATH)/dc/asic_capability/,$(ASIC_CAPABILITY_DCE112))
-+
-+AMD_DAL_FILES += $(AMD_DAL_ASIC_CAPABILITY_DCE112)
-+endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/asic_capability/asic_capability.c b/drivers/gpu/drm/amd/dal/dc/asic_capability/asic_capability.c
-index 75e0e27..aeabfc6 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
-@@ -44,6 +44,10 @@
- #include "carrizo_asic_capability.h"
- #endif
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+#include "polaris10_asic_capability.h"
-+#endif
-+
- /*
- * Initializes asic_capability instance.
- */
-@@ -108,7 +112,8 @@ static bool construct(
- asic_supported = true;
- #endif
- break;
-- case FAMILY_VI:
-+
-+ case FAMILY_VI:
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- if (ASIC_REV_IS_TONGA_P(init->hw_internal_rev) ||
- ASIC_REV_IS_FIJI_P(init->hw_internal_rev)) {
-@@ -117,7 +122,15 @@ static bool construct(
- break;
- }
- #endif
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ if (ASIC_REV_IS_POLARIS10_P(init->hw_internal_rev) ||
-+ ASIC_REV_IS_POLARIS11_M(init->hw_internal_rev)) {
-+ polaris10_asic_capability_create(cap, init);
-+ asic_supported = true;
-+ }
-+#endif
- break;
-+
- default:
- /* unsupported "chip_family" */
- break;
-diff --git a/drivers/gpu/drm/amd/dal/dc/asic_capability/polaris10_asic_capability.c b/drivers/gpu/drm/amd/dal/dc/asic_capability/polaris10_asic_capability.c
-new file mode 100644
-index 0000000..9e4fdfa
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/asic_capability/polaris10_asic_capability.c
-@@ -0,0 +1,146 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dm_services.h"
-+
-+#include "include/asic_capability_interface.h"
-+#include "include/asic_capability_types.h"
-+
-+#include "polaris10_asic_capability.h"
-+
-+#include "atom.h"
-+#include "dce/dce_11_2_d.h"
-+#include "dce/dce_11_2_sh_mask.h"
-+#include "dal_asic_id.h"
-+
-+#define ixVCE_HARVEST_FUSE_MACRO__ADDRESS 0xC0014074
-+
-+/*
-+ * carrizo_asic_capability_create
-+ *
-+ * Create and initiate Carrizo capability.
-+ */
-+void polaris10_asic_capability_create(struct asic_capability *cap,
-+ struct hw_asic_id *init)
-+{
-+ uint32_t e_fuse_setting;
-+ /* ASIC data */
-+ if (ASIC_REV_IS_POLARIS11_M(init->hw_internal_rev)) {
-+ cap->data[ASIC_DATA_CONTROLLERS_NUM] = 5;
-+ cap->data[ASIC_DATA_FUNCTIONAL_CONTROLLERS_NUM] = 5;
-+ cap->data[ASIC_DATA_LINEBUFFER_NUM] = 5;
-+ cap->data[ASIC_DATA_DIGFE_NUM] = 5;
-+ cap->data[ASIC_DATA_CLOCKSOURCES_NUM] = 7;
-+ cap->data[ASIC_DATA_MAX_COFUNC_NONDP_DISPLAYS] = 5;
-+ cap->data[ASIC_DATA_SUPPORTED_HDMI_CONNECTION_NUM] = 5;
-+ } else {
-+ cap->data[ASIC_DATA_CONTROLLERS_NUM] = 6;
-+ cap->data[ASIC_DATA_FUNCTIONAL_CONTROLLERS_NUM] = 6;
-+ cap->data[ASIC_DATA_LINEBUFFER_NUM] = 6;
-+ cap->data[ASIC_DATA_DIGFE_NUM] = 6;
-+ cap->data[ASIC_DATA_CLOCKSOURCES_NUM] = 8;
-+ cap->data[ASIC_DATA_MAX_COFUNC_NONDP_DISPLAYS] = 6;
-+ cap->data[ASIC_DATA_SUPPORTED_HDMI_CONNECTION_NUM] = 6;
-+ }
-+
-+ cap->data[ASIC_DATA_PATH_NUM_PER_DPMST_CONNECTOR] = 4;
-+ cap->data[ASIC_DATA_DCE_VERSION] = 0x112; /* DCE 11 */
-+ cap->data[ASIC_DATA_LINEBUFFER_SIZE] = 5124 * 144;
-+ cap->data[ASIC_DATA_DRAM_BANDWIDTH_EFFICIENCY] = 70;
-+
-+ cap->data[ASIC_DATA_MC_LATENCY] = 3000;
-+ cap->data[ASIC_DATA_STUTTERMODE] = 0x200A;
-+ cap->data[ASIC_DATA_VIEWPORT_PIXEL_GRANULARITY] = 2;
-+
-+ cap->data[ASIC_DATA_MEMORYTYPE_MULTIPLIER] = 4;
-+ cap->data[ASIC_DATA_DEFAULT_I2C_SPEED_IN_KHZ] = 100;
-+ cap->data[ASIC_DATA_NUM_OF_VIDEO_PLANES] = 0;
-+
-+ cap->data[ASIC_DATA_MIN_DISPCLK_FOR_UNDERSCAN] = 300000;
-+
-+ /* ASIC basic capability */
-+ cap->caps.IS_FUSION = true;
-+ cap->caps.DP_MST_SUPPORTED = true;
-+ cap->caps.PANEL_SELF_REFRESH_SUPPORTED = true;
-+ cap->caps.MIRABILIS_SUPPORTED = true;
-+ cap->caps.NO_VCC_OFF_HPD_POLLING = true;
-+ cap->caps.VCE_SUPPORTED = true;
-+ cap->caps.HPD_CHECK_FOR_EDID = true;
-+ cap->caps.DFSBYPASS_DYNAMIC_SUPPORT = true;
-+ cap->caps.SUPPORT_8BPP = false;
-+
-+ /* ASIC stereo 3d capability */
-+ cap->stereo_3d_caps.DISPLAY_BASED_ON_WS = true;
-+ cap->stereo_3d_caps.HDMI_FRAME_PACK = true;
-+ cap->stereo_3d_caps.INTERLACE_FRAME_PACK = true;
-+ cap->stereo_3d_caps.DISPLAYPORT_FRAME_PACK = true;
-+ cap->stereo_3d_caps.DISPLAYPORT_FRAME_ALT = true;
-+ cap->stereo_3d_caps.INTERLEAVE = true;
-+
-+ e_fuse_setting = dm_read_index_reg(cap->ctx,CGS_IND_REG__SMC, ixVCE_HARVEST_FUSE_MACRO__ADDRESS);
-+
-+ /* Bits [28:27]*/
-+ switch ((e_fuse_setting >> 27) & 0x3) {
-+ case 0:
-+ /*both VCE engine are working*/
-+ cap->caps.VCE_SUPPORTED = true;
-+ cap->caps.WIRELESS_TIMING_ADJUSTMENT = false;
-+ /*TODO:
-+ cap->caps.wirelessLowVCEPerformance = false;
-+ m_AsicCaps.vceInstance0Enabled = true;
-+ m_AsicCaps.vceInstance1Enabled = true;*/
-+ cap->caps.NEED_MC_TUNING = true;
-+ break;
-+
-+ case 1:
-+ cap->caps.VCE_SUPPORTED = true;
-+ cap->caps.WIRELESS_TIMING_ADJUSTMENT = true;
-+ /*TODO:
-+ m_AsicCaps.wirelessLowVCEPerformance = false;
-+ m_AsicCaps.vceInstance1Enabled = true;*/
-+ cap->caps.NEED_MC_TUNING = true;
-+ break;
-+
-+ case 2:
-+ cap->caps.VCE_SUPPORTED = true;
-+ cap->caps.WIRELESS_TIMING_ADJUSTMENT = true;
-+ /*TODO:
-+ m_AsicCaps.wirelessLowVCEPerformance = false;
-+ m_AsicCaps.vceInstance0Enabled = true;*/
-+ cap->caps.NEED_MC_TUNING = true;
-+ break;
-+
-+ case 3:
-+ /* VCE_DISABLE = 0x3 - both VCE
-+ * instances are in harvesting,
-+ * no VCE supported any more.
-+ */
-+ cap->caps.VCE_SUPPORTED = false;
-+ break;
-+
-+ default:
-+ break;
-+ }
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/asic_capability/polaris10_asic_capability.h b/drivers/gpu/drm/amd/dal/dc/asic_capability/polaris10_asic_capability.h
-new file mode 100644
-index 0000000..c8aebe1
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/asic_capability/polaris10_asic_capability.h
-@@ -0,0 +1,36 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_POLARIS10_ASIC_CAPABILITY_H__
-+#define __DAL_POLARIS10_ASIC_CAPABILITY_H__
-+
-+/* Forward declaration */
-+struct asic_capability;
-+
-+/* Create and initialize Polaris10 data */
-+void polaris10_asic_capability_create(struct asic_capability *cap,
-+ struct hw_asic_id *init);
-+
-+#endif /* __DAL_POLARIS10_ASIC_CAPABILITY_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/Makefile b/drivers/gpu/drm/amd/dal/dc/audio/Makefile
-index 2433d90..9a9a64c 100644
---- a/drivers/gpu/drm/amd/dal/dc/audio/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/Makefile
-@@ -32,3 +32,11 @@ AMD_DAL_AUDIO_DCE11 = $(addprefix $(AMDDALPATH)/dc/audio/dce110/,$(AUDIO_DCE11))
-
- AMD_DAL_FILES += $(AMD_DAL_AUDIO_DCE11)
- endif
-+
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_2
-+AUDIO_DCE112 = audio_dce112.o hw_ctx_audio_dce112.o
-+
-+AMD_DAL_AUDIO_DCE112 = $(addprefix $(AMDDALPATH)/dc/audio/dce112/,$(AUDIO_DCE112))
-+
-+AMD_DAL_FILES += $(AMD_DAL_AUDIO_DCE112)
-+endif
-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 c297d95..a8137e0 100644
---- a/drivers/gpu/drm/amd/dal/dc/audio/audio_base.c
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/audio_base.c
-@@ -40,6 +40,11 @@
- #include "dce110/hw_ctx_audio_dce110.h"
- #endif
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+#include "dce112/audio_dce112.h"
-+#include "dce112/hw_ctx_audio_dce112.h"
-+#endif
-+
- /***** static function : only used within audio.c *****/
-
- /* stub for hook functions */
-@@ -281,6 +286,10 @@ struct audio *dal_audio_create(
- case DCE_VERSION_11_0:
- return dal_audio_create_dce110(init_data);
- #endif
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ case DCE_VERSION_11_2:
-+ return dal_audio_create_dce112(init_data);
-+#endif
- default:
- BREAK_TO_DEBUGGER();
- return NULL;
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/dce112/audio_dce112.c b/drivers/gpu/drm/amd/dal/dc/audio/dce112/audio_dce112.c
-new file mode 100644
-index 0000000..66c32b0
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/dce112/audio_dce112.c
-@@ -0,0 +1,451 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 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_dce112.h"
-+
-+/***** static functions *****/
-+
-+static void destruct(struct audio_dce112 *audio)
-+{
-+ /*release memory allocated for hw_ctx -- allocated is initiated
-+ *by audio_dce112 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_dce112 *audio = NULL;
-+
-+ audio = container_of(*ptr, struct audio_dce112, base);
-+
-+ destruct(audio);
-+
-+ /* release memory allocated for audio_dce112*/
-+ dm_free(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_dce112.
-+ */
-+
-+/**
-+* setup
-+*
-+* @brief
-+* setup Audio HW block, to be called by dal_audio_setup
-+*
-+*/
-+static enum audio_result setup(
-+ struct audio *audio,
-+ struct audio_output *output,
-+ struct audio_info *info)
-+{
-+ switch (output->signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ /*setup HDMI audio engine*/
-+ audio->hw_ctx->funcs->enable_afmt_clock(
-+ audio->hw_ctx,
-+ output->engine_id,
-+ true);
-+ audio->hw_ctx->funcs->setup_hdmi_audio(
-+ audio->hw_ctx, output->engine_id, &output->crtc_info);
-+
-+ audio->hw_ctx->funcs->setup_azalia(
-+ audio->hw_ctx,
-+ output->engine_id,
-+ output->signal,
-+ &output->crtc_info,
-+ &output->pll_info,
-+ info);
-+ break;
-+
-+ case SIGNAL_TYPE_WIRELESS:
-+ /* setup Azalia block for Wireless Display - This
-+ is different than for wired
-+ displays because there is no
-+ DIG to program.*/
-+ /*TODO:
-+ audio->hw_ctx->funcs->setup_azalia_for_vce(
-+ audio->hw_ctx,
-+ audio->signal,
-+ audio->crtc_info,
-+ info);
-+ */
-+ break;
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP:
-+ /* setup DP audio engine will be done at enable output */
-+
-+ /* setup Azalia block*/
-+ audio->hw_ctx->funcs->setup_azalia(
-+ audio->hw_ctx,
-+ output->engine_id,
-+ output->signal,
-+ &output->crtc_info,
-+ &output->pll_info,
-+ info);
-+
-+ break;
-+ default:
-+ return AUDIO_RESULT_ERROR;
-+ }
-+
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/**
-+* enable_output
-+*
-+* @brief
-+* enable Audio HW block, to be called by dal_audio_enable_output
-+*/
-+static enum audio_result enable_output(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ /* enable audio output */
-+ switch (signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ break;
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP: {
-+ /* enable AFMT clock before enable audio*/
-+ audio->hw_ctx->funcs->enable_afmt_clock(
-+ audio->hw_ctx, engine_id, true);
-+ /* setup DP audio engine */
-+ audio->hw_ctx->funcs->setup_dp_audio(
-+ audio->hw_ctx, engine_id);
-+ /* enabl DP audio packets will be done at unblank */
-+ audio->hw_ctx->funcs->enable_dp_audio(
-+ audio->hw_ctx, engine_id);
-+ }
-+ break;
-+ case SIGNAL_TYPE_WIRELESS:
-+ /* route audio to VCE block */
-+ audio->hw_ctx->funcs->setup_vce_audio(audio->hw_ctx);
-+ break;
-+ default:
-+ return AUDIO_RESULT_ERROR;
-+ }
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/**
-+* disable_output
-+*
-+* @brief
-+* disable Audio HW block, to be called by dal_audio_disable_output
-+*
-+*/
-+static enum audio_result disable_output(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ switch (signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ case SIGNAL_TYPE_WIRELESS:
-+ /* disable HDMI audio */
-+ audio->hw_ctx->
-+ funcs->disable_azalia_audio(
-+ audio->hw_ctx, engine_id);
-+ audio->hw_ctx->
-+ funcs->enable_afmt_clock(
-+ audio->hw_ctx, engine_id,
-+ false);
-+
-+ break;
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP: {
-+ /* disable DP audio */
-+ audio->hw_ctx->funcs->disable_dp_audio(
-+ audio->hw_ctx, engine_id);
-+ audio->hw_ctx->funcs->disable_azalia_audio(
-+ audio->hw_ctx, engine_id);
-+ audio->hw_ctx->funcs->enable_afmt_clock(
-+ audio->hw_ctx, engine_id, false);
-+ }
-+ break;
-+ default:
-+ return AUDIO_RESULT_ERROR;
-+ }
-+
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/**
-+* unmute
-+*
-+* @brief
-+* unmute audio, to be called by dal_audio_unmute
-+*
-+*/
-+static enum audio_result unmute(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ switch (signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP:
-+ /* unmute Azalia audio */
-+ audio->hw_ctx->funcs->unmute_azalia_audio(
-+ audio->hw_ctx, engine_id);
-+ break;
-+ case SIGNAL_TYPE_WIRELESS:
-+ /*Do nothing for wireless display*/
-+ break;
-+ default:
-+ return AUDIO_RESULT_ERROR;
-+ }
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/**
-+* mute
-+*
-+* @brief
-+* mute audio, to be called by dal_audio_nmute
-+*
-+*/
-+static enum audio_result mute(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal)
-+{
-+ switch (signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ case SIGNAL_TYPE_EDP:
-+ /* mute Azalia audio */
-+ audio->hw_ctx->funcs->mute_azalia_audio(
-+ audio->hw_ctx, engine_id);
-+ break;
-+ case SIGNAL_TYPE_WIRELESS:
-+ /*Do nothing for wireless display*/
-+ break;
-+ default:
-+ return AUDIO_RESULT_ERROR;
-+ }
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/**
-+* initialize
-+*
-+* @brief
-+* Perform SW initialization - create audio hw context. Then do HW
-+* initialization. this function is called at dal_audio_power_up.
-+*
-+*/
-+static enum audio_result initialize(
-+ struct audio *audio)
-+{
-+ uint8_t audio_endpoint_enum_id = 0;
-+
-+ audio_endpoint_enum_id = audio->id.enum_id;
-+
-+ /* HW CTX already create*/
-+ if (audio->hw_ctx != NULL)
-+ return AUDIO_RESULT_OK;
-+
-+ audio->hw_ctx = dal_hw_ctx_audio_dce112_create(
-+ audio->ctx,
-+ audio_endpoint_enum_id);
-+
-+ if (audio->hw_ctx == NULL)
-+ return AUDIO_RESULT_ERROR;
-+
-+ /* override HW default settings */
-+ audio->hw_ctx->funcs->hw_initialize(audio->hw_ctx);
-+
-+ return AUDIO_RESULT_OK;
-+}
-+
-+/* enable multi channel split */
-+static void enable_channel_splitting_mapping(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ const struct audio_channel_associate_info *audio_mapping,
-+ bool enable)
-+{
-+ audio->hw_ctx->funcs->setup_channel_splitting_mapping(
-+ audio->hw_ctx,
-+ engine_id,
-+ signal,
-+ audio_mapping, enable);
-+}
-+
-+/* get current multi channel split. */
-+static enum audio_result get_channel_splitting_mapping(
-+ struct audio *audio,
-+ enum engine_id engine_id,
-+ struct audio_channel_associate_info *audio_mapping)
-+{
-+ if (audio->hw_ctx->funcs->get_channel_splitting_mapping(
-+ audio->hw_ctx, engine_id, audio_mapping)) {
-+ return AUDIO_RESULT_OK;
-+ } else {
-+ return AUDIO_RESULT_ERROR;
-+ }
-+}
-+
-+/**
-+* set_unsolicited_response_payload
-+*
-+* @brief
-+* Set payload value for the unsolicited response
-+*/
-+static void set_unsolicited_response_payload(
-+ struct audio *audio,
-+ enum audio_payload payload)
-+{
-+ audio->hw_ctx->funcs->set_unsolicited_response_payload(
-+ audio->hw_ctx, payload);
-+}
-+
-+/**
-+* setup_audio_wall_dto
-+*
-+* @brief
-+* Update audio source clock from hardware context.
-+*
-+*/
-+static void setup_audio_wall_dto(
-+ struct audio *audio,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_pll_info *pll_info)
-+{
-+ audio->hw_ctx->funcs->setup_audio_wall_dto(
-+ audio->hw_ctx, signal, crtc_info, pll_info);
-+}
-+
-+/**
-+* get_supported_features
-+*
-+* @brief
-+* options and features supported by Audio
-+* returns supported engines, signals.
-+* features are reported for HW audio/Azalia block rather then Audio object
-+* itself the difference for DCE6.x is that MultiStream Audio is now supported
-+*
-+*/
-+static struct audio_feature_support get_supported_features(struct audio *audio)
-+{
-+ struct audio_feature_support afs = {0};
-+
-+ afs.ENGINE_DIGA = 1;
-+ afs.ENGINE_DIGB = 1;
-+ afs.ENGINE_DIGC = 1;
-+ afs.MULTISTREAM_AUDIO = 1;
-+
-+ return afs;
-+}
-+
-+static const struct audio_funcs funcs = {
-+ .destroy = destroy,
-+ .setup = setup,
-+ .enable_output = enable_output,
-+ .disable_output = disable_output,
-+ .unmute = unmute,
-+ .mute = mute,
-+ .initialize = initialize,
-+ .enable_channel_splitting_mapping =
-+ enable_channel_splitting_mapping,
-+ .get_channel_splitting_mapping =
-+ get_channel_splitting_mapping,
-+ .set_unsolicited_response_payload =
-+ set_unsolicited_response_payload,
-+ .setup_audio_wall_dto = setup_audio_wall_dto,
-+ .get_supported_features = get_supported_features,
-+};
-+
-+static bool construct(
-+ struct audio_dce112 *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_dce112(
-+ const struct audio_init_data *init_data)
-+{
-+ /*allocate memory for audio_dce112 */
-+ struct audio_dce112 *audio = dm_alloc(sizeof(*audio));
-+
-+ if (audio == NULL) {
-+ ASSERT_CRITICAL(audio);
-+ return NULL;
-+ }
-+ /*pointer to base_audio_block of audio_dce112 ==> audio base object */
-+ if (construct(audio, init_data))
-+ return &audio->base;
-+
-+ dal_logger_write(
-+ init_data->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_AUDIO,
-+ "Failed to create audio object for DCE11\n");
-+
-+ /*release memory allocated if fail */
-+ dm_free(audio);
-+ return NULL;
-+}
-+
-+/* Do not need expose construct_dce112 and destruct_dce112 becuase there is
-+ *derived object after dce112
-+ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/dce112/audio_dce112.h b/drivers/gpu/drm/amd/dal/dc/audio/dce112/audio_dce112.h
-new file mode 100644
-index 0000000..7c8d71c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/dce112/audio_dce112.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_AUDIO_DCE_112_H__
-+#define __DAL_AUDIO_DCE_112_H__
-+
-+#include "audio/audio.h"
-+#include "audio/hw_ctx_audio.h"
-+#include "audio/dce112/hw_ctx_audio_dce112.h"
-+
-+struct audio_dce112 {
-+ struct audio base;
-+ /* dce-specific members are following */
-+ /* none */
-+};
-+
-+struct audio *dal_audio_create_dce112(const struct audio_init_data *init_data);
-+
-+#endif /*__DAL_AUDIO_DCE_112_H__*/
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/dce112/hw_ctx_audio_dce112.c b/drivers/gpu/drm/amd/dal/dc/audio/dce112/hw_ctx_audio_dce112.c
-new file mode 100644
-index 0000000..95cb86f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/dce112/hw_ctx_audio_dce112.c
-@@ -0,0 +1,1923 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 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 "hw_ctx_audio_dce112.h"
-+
-+#include "dce/dce_11_2_d.h"
-+#include "dce/dce_11_2_sh_mask.h"
-+
-+#define FROM_BASE(ptr) \
-+ container_of((ptr), struct hw_ctx_audio_dce112, base)
-+
-+#define DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT 0x8000
-+#define DP_AUDIO_DTO_MODULE_WITHOUT_SS 360
-+#define DP_AUDIO_DTO_PHASE_WITHOUT_SS 24
-+
-+#define DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUDIO_FRONT_END 0
-+#define DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC 1
-+#define DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__REGISTER_PROGRAMMABLE 2
-+
-+#define FIRST_AUDIO_STREAM_ID 1
-+
-+#define NOT_IMPLEMENTED() DAL_LOGGER_NOT_IMPL(LOG_MINOR_COMPONENT_AUDIO, \
-+ "Audio:%s()\n", __func__)
-+
-+static const uint32_t engine_offset[] = {
-+ 0,
-+ mmDIG1_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+ mmDIG2_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+ mmDIG3_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+ mmDIG4_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL,
-+ mmDIG5_DIG_FE_CNTL - mmDIG0_DIG_FE_CNTL
-+};
-+
-+static void destruct(
-+ struct hw_ctx_audio_dce112 *hw_ctx_dce112)
-+{
-+ dal_audio_destruct_hw_ctx_audio(&hw_ctx_dce112->base);
-+}
-+
-+static void destroy(
-+ struct hw_ctx_audio **ptr)
-+{
-+ struct hw_ctx_audio_dce112 *hw_ctx_dce112;
-+
-+ hw_ctx_dce112 = container_of(
-+ *ptr, struct hw_ctx_audio_dce112, base);
-+
-+ destruct(hw_ctx_dce112);
-+ /* release memory allocated for struct hw_ctx_audio_dce112 */
-+ dm_free(hw_ctx_dce112);
-+
-+ *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)
-+{
-+ uint32_t value = 0;
-+
-+ if (hbr_channel_count > 7)
-+ return;
-+
-+ value = dal_read_reg(hw_ctx->ctx,
-+ mmAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL);
-+
-+ set_reg_field_value(value, hbr_channel_count,
-+ AZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL,
-+ HBR_CHANNEL_COUNT);
-+
-+ dal_write_reg(hw_ctx->ctx,
-+ mmAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL, value);
-+
-+}
-+
-+*set compressed audio channel count *
-+static void set_compressed_audio_channel_count(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t compressed_audio_ch_count)
-+{
-+ uint32_t value = 0;
-+ if (compressed_audio_ch_count > 7)
-+ return;
-+
-+ value = dal_read_reg(hw_ctx->ctx,
-+ mmAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL);
-+
-+ set_reg_field_value(value, compressed_audio_ch_count,
-+ AZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL,
-+ COMPRESSED_CHANNEL_COUNT);
-+
-+ dal_write_reg(hw_ctx->ctx,
-+ mmAZALIA_F0_CODEC_CHANNEL_COUNT_CONTROL,
-+ value);
-+
-+}
-+*/
-+/* set video latency in in ms/2+1 */
-+static void set_video_latency(
-+ const struct hw_ctx_audio *hw_ctx,
-+ int latency_in_ms)
-+{
-+ uint32_t value = 0;
-+
-+ if ((latency_in_ms < 0) || (latency_in_ms > 255))
-+ return;
-+
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);
-+
-+ set_reg_field_value(value, latency_in_ms,
-+ AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
-+ VIDEO_LIPSYNC);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
-+ value);
-+
-+}
-+
-+/* set audio latency in in ms/2+1 */
-+static void set_audio_latency(
-+ const struct hw_ctx_audio *hw_ctx,
-+ int latency_in_ms)
-+{
-+ uint32_t value = 0;
-+
-+ if (latency_in_ms < 0)
-+ latency_in_ms = 0;
-+
-+ if (latency_in_ms > 255)
-+ latency_in_ms = 255;
-+
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);
-+
-+ set_reg_field_value(value, latency_in_ms,
-+ AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
-+ AUDIO_LIPSYNC);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
-+ value);
-+
-+}
-+
-+/* enable HW/SW Sync */
-+/*static void enable_hw_sw_sync(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ union AZALIA_CYCLIC_BUFFER_SYNC value;
-+
-+ value = dal_read_reg(mmAZALIA_CYCLIC_BUFFER_SYNC);
-+ value.bits.CYCLIC_BUFFER_SYNC_ENABLE = 1;
-+ dal_write_reg(mmAZALIA_CYCLIC_BUFFER_SYNC, value);
-+}*/
-+
-+/* disable HW/SW Sync */
-+/*static void disable_hw_sw_sync(
-+ const struct hw_ctx_audio *hw_ctx)
-+{
-+ union AZALIA_CYCLIC_BUFFER_SYNC value;
-+
-+ value = dal_read_reg(
-+ mmAZALIA_CYCLIC_BUFFER_SYNC);
-+ value.bits.CYCLIC_BUFFER_SYNC_ENABLE = 0;
-+ dal_write_reg(
-+ mmAZALIA_CYCLIC_BUFFER_SYNC, value);
-+}*/
-+
-+/* update hardware with software's current position in cyclic buffer */
-+/*static void update_sw_write_ptr(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t offset)
-+{
-+ union AZALIA_APPLICATION_POSITION_IN_CYCLIC_BUFFER value;
-+
-+ value = dal_read_reg(
-+ mmAZALIA_APPLICATION_POSITION_IN_CYCLIC_BUFFER);
-+ value.bits.APPLICATION_POSITION_IN_CYCLIC_BUFFER = offset;
-+ dal_write_reg(
-+ mmAZALIA_APPLICATION_POSITION_IN_CYCLIC_BUFFER,
-+ value);
-+}*/
-+
-+/* update Audio/Video association */
-+/*static void update_av_association(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ enum signal_type signal,
-+ uint32_t displayId)
-+{
-+
-+}*/
-+
-+/* --- hook functions --- */
-+static bool get_azalia_clock_info_hdmi(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t crtc_pixel_clock_in_khz,
-+ uint32_t actual_pixel_clock_in_khz,
-+ struct azalia_clock_info *azalia_clock_info);
-+
-+static bool get_azalia_clock_info_dp(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t requested_pixel_clock_in_khz,
-+ const struct audio_pll_info *pll_info,
-+ struct azalia_clock_info *azalia_clock_info);
-+
-+static void setup_audio_wall_dto(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum signal_type signal,
-+ const struct audio_crtc_info *crtc_info,
-+ const struct audio_pll_info *pll_info)
-+{
-+ struct azalia_clock_info clock_info = { 0 };
-+
-+ uint32_t value = 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)
-+{
-+ struct dc_context *ctx = hw_ctx->ctx;
-+
-+ NOT_IMPLEMENTED();
-+
-+ /*TODO:
-+ const uint32_t addr = mmDOUT_DCE_VCE_CONTROL;
-+ uint32_t value = 0;
-+
-+ value = dal_read_reg(hw_ctx->ctx,
-+ addr);
-+
-+ set_reg_field_value(value,
-+ FROM_BASE(hw_ctx)->azalia_stream_id - 1,
-+ DOUT_DCE_VCE_CONTROL,
-+ DC_VCE_AUDIO_STREAM_SELECT);
-+
-+ dal_write_reg(hw_ctx->ctx,
-+ addr, value);*/
-+}
-+
-+static void enable_afmt_clock(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id,
-+ bool enable_flag)
-+{
-+ uint32_t engine_offs = engine_offset[engine_id];
-+ uint32_t value;
-+ uint32_t count = 0;
-+ uint32_t enable = enable_flag ? 1:0;
-+
-+ /* Enable Audio packets*/
-+ value = dm_read_reg(hw_ctx->ctx, mmAFMT_CNTL + engine_offs);
-+
-+ /*enable AFMT clock*/
-+ set_reg_field_value(value, enable,
-+ AFMT_CNTL, AFMT_AUDIO_CLOCK_EN);
-+ dm_write_reg(hw_ctx->ctx, mmAFMT_CNTL + engine_offs, value);
-+
-+ /*wait for AFMT clock to turn on,
-+ * the expectation is that this
-+ * should complete in 1-2 reads)
-+ */
-+ do {
-+ /* Wait for 1us between subsequent register reads.*/
-+ udelay(1);
-+ value = dm_read_reg(hw_ctx->ctx,
-+ mmAFMT_CNTL + engine_offs);
-+ } while (get_reg_field_value(value,
-+ AFMT_CNTL, AFMT_AUDIO_CLOCK_ON) !=
-+ enable && count++ < 10);
-+}
-+
-+/* enable Azalia audio */
-+static void enable_azalia_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ uint32_t value;
-+
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
-+
-+ if (get_reg_field_value(value,
-+ AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
-+ AUDIO_ENABLED) != 1)
-+ set_reg_field_value(value, 1,
-+ AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
-+ AUDIO_ENABLED);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
-+ value);
-+}
-+
-+/* disable Azalia audio */
-+static void disable_azalia_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ uint32_t value;
-+
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
-+
-+ set_reg_field_value(value, 0,
-+ AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
-+ AUDIO_ENABLED);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
-+ value);
-+}
-+
-+/* enable DP audio */
-+static void enable_dp_audio(
-+ const struct hw_ctx_audio *hw_ctx,
-+ enum engine_id engine_id)
-+{
-+ const uint32_t addr = mmDP_SEC_CNTL + engine_offset[engine_id];
-+
-+ uint32_t value;
-+
-+ /* Enable Audio packets */
-+ value = 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);
-+
-+ /* LFE_PLAYBACK_LEVEL = LFEPBL
-+ * LFEPBL = 0 : Unknown or refer to other information
-+ * LFEPBL = 1 : 0dB playback
-+ * LFEPBL = 2 : +10dB playback
-+ * LFE_BL = 3 : Reserved
-+ */
-+ set_reg_field_value(value,
-+ 0,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ LFE_PLAYBACK_LEVEL);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ HDMI_CONNECTION);
-+
-+ set_reg_field_value(value,
-+ 0,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ DP_CONNECTION);
-+
-+ field = get_reg_field_value(value,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ EXTRA_CONNECTION_INFO);
-+
-+ field &= ~0x1;
-+
-+ set_reg_field_value(value,
-+ field,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ EXTRA_CONNECTION_INFO);
-+
-+ /* set audio for output signal */
-+ switch (signal) {
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ set_reg_field_value(value,
-+ 1,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ HDMI_CONNECTION);
-+
-+ break;
-+ case SIGNAL_TYPE_WIRELESS: {
-+ /*LSB used for "is wireless" flag */
-+ field = 0;
-+ field = get_reg_field_value(value,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ EXTRA_CONNECTION_INFO);
-+ field |= 0x1;
-+ set_reg_field_value(value,
-+ field,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ EXTRA_CONNECTION_INFO);
-+
-+ set_reg_field_value(value,
-+ 1,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ HDMI_CONNECTION);
-+
-+ }
-+ break;
-+ case SIGNAL_TYPE_EDP:
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ set_reg_field_value(value,
-+ 1,
-+ AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ DP_CONNECTION);
-+
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
-+ value);
-+
-+ /* Wireless Display identification */
-+ value = read_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION);
-+
-+ set_reg_field_value(value,
-+ signal == SIGNAL_TYPE_WIRELESS ? 1 : 0,
-+ AZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION,
-+ WIRELESS_DISPLAY_IDENTIFICATION);
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_WIRELESS_DISPLAY_IDENTIFICATION,
-+ value);
-+
-+ /* Audio Descriptors */
-+ /* pass through all formats */
-+ for (format_index = 0; format_index < AUDIO_FORMAT_CODE_COUNT;
-+ format_index++) {
-+ audio_format_code =
-+ (AUDIO_FORMAT_CODE_FIRST + format_index);
-+
-+ /* those are unsupported, skip programming */
-+ if (audio_format_code == AUDIO_FORMAT_CODE_1BITAUDIO ||
-+ audio_format_code == AUDIO_FORMAT_CODE_DST)
-+ continue;
-+
-+ value = 0;
-+
-+ /* check if supported */
-+ is_audio_format_supported =
-+ dal_audio_hw_ctx_is_audio_format_supported(
-+ hw_ctx,
-+ audio_info,
-+ audio_format_code, &index);
-+
-+ if (is_audio_format_supported) {
-+ const struct audio_mode *audio_mode =
-+ &audio_info->modes[index];
-+ union audio_sample_rates sample_rates =
-+ audio_mode->sample_rates;
-+ uint8_t byte2 = audio_mode->max_bit_rate;
-+
-+ /* adjust specific properties */
-+ switch (audio_format_code) {
-+ case AUDIO_FORMAT_CODE_LINEARPCM: {
-+ dal_hw_ctx_audio_check_audio_bandwidth(
-+ hw_ctx,
-+ crtc_info,
-+ audio_mode->channel_count,
-+ signal,
-+ &sample_rates);
-+
-+ byte2 = audio_mode->sample_size;
-+
-+ set_reg_field_value(value,
-+ sample_rates.all,
-+ AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
-+ SUPPORTED_FREQUENCIES_STEREO);
-+
-+ }
-+ break;
-+ case AUDIO_FORMAT_CODE_AC3:
-+ is_ac3_supported = true;
-+ break;
-+ case AUDIO_FORMAT_CODE_DOLBYDIGITALPLUS:
-+ case AUDIO_FORMAT_CODE_DTS_HD:
-+ case AUDIO_FORMAT_CODE_MAT_MLP:
-+ case AUDIO_FORMAT_CODE_DST:
-+ case AUDIO_FORMAT_CODE_WMAPRO:
-+ byte2 = audio_mode->vendor_specific;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ /* fill audio format data */
-+ set_reg_field_value(value,
-+ audio_mode->channel_count - 1,
-+ AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
-+ MAX_CHANNELS);
-+
-+ set_reg_field_value(value,
-+ sample_rates.all,
-+ AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
-+ SUPPORTED_FREQUENCIES);
-+
-+ set_reg_field_value(value,
-+ byte2,
-+ AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
-+ DESCRIPTOR_BYTE_2);
-+
-+ } /* if */
-+
-+ write_indirect_azalia_reg(
-+ hw_ctx,
-+ ixAZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 +
-+ format_index,
-+ value);
-+ } /* for */
-+
-+ if (is_ac3_supported)
-+ 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);
-+}
-+
-+/* search pixel clock value for Azalia HDMI Audio */
-+static bool get_azalia_clock_info_hdmi(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t crtc_pixel_clock_in_khz,
-+ uint32_t actual_pixel_clock_in_khz,
-+ struct azalia_clock_info *azalia_clock_info)
-+{
-+ if (azalia_clock_info == NULL)
-+ return false;
-+
-+ /* audio_dto_phase= 24 * 10,000;
-+ * 24MHz in [100Hz] units */
-+ azalia_clock_info->audio_dto_phase =
-+ 24 * 10000;
-+
-+ /* audio_dto_module = PCLKFrequency * 10,000;
-+ * [khz] -> [100Hz] */
-+ azalia_clock_info->audio_dto_module =
-+ actual_pixel_clock_in_khz * 10;
-+
-+ return true;
-+}
-+
-+/* search pixel clock value for Azalia DP Audio */
-+static bool get_azalia_clock_info_dp(
-+ const struct hw_ctx_audio *hw_ctx,
-+ uint32_t requested_pixel_clock_in_khz,
-+ const struct audio_pll_info *pll_info,
-+ struct azalia_clock_info *azalia_clock_info)
-+{
-+ if (pll_info == NULL || azalia_clock_info == NULL)
-+ return false;
-+
-+ /* Reported dpDtoSourceClockInkhz value for
-+ * DCE8 already adjusted for SS, do not need any
-+ * adjustment here anymore
-+ */
-+
-+ /*audio_dto_phase = 24 * 10,000;
-+ * 24MHz in [100Hz] units */
-+ azalia_clock_info->audio_dto_phase = 24 * 10000;
-+
-+ /*audio_dto_module = dpDtoSourceClockInkhz * 10,000;
-+ * [khz] ->[100Hz] */
-+ azalia_clock_info->audio_dto_module =
-+ pll_info->dp_dto_source_clock_in_khz * 10;
-+
-+ return true;
-+}
-+
-+static const struct hw_ctx_audio_funcs funcs = {
-+ .destroy = destroy,
-+ .setup_audio_wall_dto =
-+ setup_audio_wall_dto,
-+ .setup_hdmi_audio =
-+ setup_hdmi_audio,
-+ .setup_dp_audio = setup_dp_audio,
-+ .setup_vce_audio = setup_vce_audio,
-+ .enable_azalia_audio =
-+ enable_azalia_audio,
-+ .disable_azalia_audio =
-+ disable_azalia_audio,
-+ .enable_dp_audio =
-+ enable_dp_audio,
-+ .disable_dp_audio =
-+ disable_dp_audio,
-+ .setup_azalia =
-+ setup_azalia,
-+ .disable_az_clock_gating = NULL,
-+ .unmute_azalia_audio =
-+ unmute_azalia_audio,
-+ .mute_azalia_audio =
-+ mute_azalia_audio,
-+ .setup_channel_splitting_mapping =
-+ setup_channel_splitting_mapping,
-+ .get_channel_splitting_mapping =
-+ get_channel_splitting_mapping,
-+ .set_unsolicited_response_payload =
-+ set_unsolicited_response_payload,
-+ .hw_initialize =
-+ hw_initialize,
-+ .enable_gtc_embedding_with_group =
-+ enable_gtc_embedding_with_group,
-+ .disable_gtc_embedding =
-+ disable_gtc_embedding,
-+ .get_azalia_clock_info_hdmi =
-+ get_azalia_clock_info_hdmi,
-+ .get_azalia_clock_info_dp =
-+ get_azalia_clock_info_dp,
-+ .enable_afmt_clock = enable_afmt_clock
-+};
-+
-+static bool construct(
-+ struct hw_ctx_audio_dce112 *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 dce112 audio object */
-+ hw_ctx->azalia_stream_id = azalia_stream_id;
-+ hw_ctx->base.ctx = ctx;
-+
-+ /* azalia audio endpoints register offsets. azalia is associated with
-+ DIG front. save AUDIO register offset */
-+ switch (azalia_stream_id) {
-+ case 1: {
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_index =
-+ mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX;
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_data =
-+ mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA;
-+ }
-+ break;
-+ case 2: {
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_index =
-+ mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_INDEX;
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_data =
-+ mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_DATA;
-+ }
-+ break;
-+ case 3: {
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_index =
-+ mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_INDEX;
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_data =
-+ mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_DATA;
-+ }
-+ break;
-+ case 4: {
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_index =
-+ mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_INDEX;
-+ hw_ctx->az_mm_reg_offsets.
-+ azf0endpointx_azalia_f0_codec_endpoint_data =
-+ mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_DATA;
-+ }
-+ break;
-+ default:
-+ dal_logger_write(
-+ hw_ctx->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_AUDIO,
-+ "Invalid Azalia stream ID!");
-+ break;
-+ }
-+
-+ return true;
-+}
-+
-+/* audio_dce112 is derived from audio directly, not via dce80 */
-+struct hw_ctx_audio *dal_hw_ctx_audio_dce112_create(
-+ struct dc_context *ctx,
-+ uint32_t azalia_stream_id)
-+{
-+ /* allocate memory for struc hw_ctx_audio_dce112 */
-+ struct hw_ctx_audio_dce112 *hw_ctx_dce112 =
-+ dm_alloc(sizeof(struct hw_ctx_audio_dce112));
-+
-+ if (!hw_ctx_dce112) {
-+ ASSERT_CRITICAL(hw_ctx_dce112);
-+ return NULL;
-+ }
-+
-+ /*return pointer to hw_ctx_audio back to caller -- audio object */
-+ if (construct(
-+ hw_ctx_dce112, azalia_stream_id, ctx))
-+ return &hw_ctx_dce112->base;
-+
-+ dal_logger_write(
-+ ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_AUDIO,
-+ "Failed to create hw_ctx_audio for DCE11\n");
-+
-+ dm_free(hw_ctx_dce112);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/audio/dce112/hw_ctx_audio_dce112.h b/drivers/gpu/drm/amd/dal/dc/audio/dce112/hw_ctx_audio_dce112.h
-new file mode 100644
-index 0000000..af61aad
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/audio/dce112/hw_ctx_audio_dce112.h
-@@ -0,0 +1,47 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_HW_CTX_AUDIO_DCE112_H__
-+#define __DAL_HW_CTX_AUDIO_DCE112_H__
-+
-+#include "audio/hw_ctx_audio.h"
-+
-+struct hw_ctx_audio_dce112 {
-+ struct hw_ctx_audio base;
-+
-+ /* azalia stream id 1 based indexing, corresponding to audio GO enumId*/
-+ uint32_t azalia_stream_id;
-+
-+ /* azalia stream endpoint register offsets */
-+ struct azalia_reg_offsets az_mm_reg_offsets;
-+
-+ /* audio encoder block MM register offset -- associate with DIG FRONT */
-+};
-+
-+struct hw_ctx_audio *dal_hw_ctx_audio_dce112_create(
-+ struct dc_context *ctx,
-+ uint32_t azalia_stream_id);
-+
-+#endif /* __DAL_HW_CTX_AUDIO_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/Makefile b/drivers/gpu/drm/amd/dal/dc/bios/Makefile
-index e5c8876..9c90230 100644
---- a/drivers/gpu/drm/amd/dal/dc/bios/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/Makefile
-@@ -37,3 +37,12 @@ endif
-
- AMD_DAL_FILES += $(AMDDALPATH)/dc/bios/dce110/command_table_helper_dce110.o
- endif
-+
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_2
-+ccflags-y += -DLATEST_ATOM_BIOS_SUPPORT
-+ifdef CONFIG_DRM_AMD_DAL_VBIOS_PRESENT
-+AMD_DAL_FILES += $(AMDDALPATH)/dc/bios/dce112/bios_parser_helper_dce112.o
-+endif
-+
-+AMD_DAL_FILES += $(AMDDALPATH)/dc/bios/dce112/command_table_helper_dce112.o
-+endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.c b/drivers/gpu/drm/amd/dal/dc/bios/bios_parser_helper.c
-index 4e2bc90..4204798 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
-@@ -55,6 +55,12 @@ bool dal_bios_parser_init_bios_helper(
- return true;
-
- #endif
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ case DCE_VERSION_11_2:
-+ bp->bios_helper = dal_bios_parser_helper_dce112_get_table();
-+ return true;
-+
-+#endif
- default:
- BREAK_TO_DEBUGGER();
- return false;
-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 c58b9bb..b93b046 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
-@@ -34,6 +34,10 @@
- #include "dce110/bios_parser_helper_dce110.h"
- #endif
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+#include "dce112/bios_parser_helper_dce112.h"
-+#endif
-+
- struct bios_parser;
-
- struct vbios_helper_data {
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/command_table.c b/drivers/gpu/drm/amd/dal/dc/bios/command_table.c
-index ccd1c7e..22524b3 100644
---- a/drivers/gpu/drm/amd/dal/dc/bios/command_table.c
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/command_table.c
-@@ -104,6 +104,13 @@ static enum bp_result encoder_control_digx_v3(
- static enum bp_result encoder_control_digx_v4(
- struct bios_parser *bp,
- struct bp_encoder_control *cntl);
-+
-+#ifdef LATEST_ATOM_BIOS_SUPPORT
-+static enum bp_result encoder_control_digx_v5(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl);
-+#endif
-+
- static void init_encoder_control_dig_v1(struct bios_parser *bp);
-
- static void init_dig_encoder_control(struct bios_parser *bp)
-@@ -112,12 +119,19 @@ static void init_dig_encoder_control(struct bios_parser *bp)
- BIOS_CMD_TABLE_PARA_REVISION(DIGxEncoderControl);
-
- switch (version) {
-+ case 2:
-+ bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v3;
-+ break;
- case 4:
- bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v4;
- break;
-- case 2:
-- bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v3;
-+
-+#ifdef LATEST_ATOM_BIOS_SUPPORT
-+ case 5:
-+ bp->cmd_tbl.dig_encoder_control = encoder_control_digx_v5;
- break;
-+#endif
-+
- default:
- init_encoder_control_dig_v1(bp);
- break;
-@@ -302,6 +316,66 @@ static enum bp_result encoder_control_digx_v4(
- return result;
- }
-
-+#ifdef LATEST_ATOM_BIOS_SUPPORT
-+static enum bp_result encoder_control_digx_v5(
-+ struct bios_parser *bp,
-+ struct bp_encoder_control *cntl)
-+{
-+ enum bp_result result = BP_RESULT_FAILURE;
-+ ENCODER_STREAM_SETUP_PARAMETERS_V5 params = {0};
-+
-+ params.ucDigId = (uint8_t)(cntl->engine_id);
-+ params.ucAction = bp->cmd_helper->encoder_action_to_atom(cntl->action);
-+
-+ params.ulPixelClock = cntl->pixel_clock / 10;
-+ params.ucDigMode =
-+ (uint8_t)(bp->cmd_helper->encoder_mode_bp_to_atom(
-+ cntl->signal,
-+ cntl->enable_dp_audio));
-+ params.ucLaneNum = (uint8_t)(cntl->lanes_number);
-+
-+ switch (cntl->color_depth) {
-+ case COLOR_DEPTH_888:
-+ params.ucBitPerColor = PANEL_8BIT_PER_COLOR;
-+ break;
-+ case COLOR_DEPTH_101010:
-+ params.ucBitPerColor = PANEL_10BIT_PER_COLOR;
-+ break;
-+ case COLOR_DEPTH_121212:
-+ params.ucBitPerColor = PANEL_12BIT_PER_COLOR;
-+ break;
-+ case COLOR_DEPTH_161616:
-+ params.ucBitPerColor = PANEL_16BIT_PER_COLOR;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (cntl->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-+ switch (cntl->color_depth) {
-+ case COLOR_DEPTH_101010:
-+ params.ulPixelClock =
-+ (params.ulPixelClock * 30) / 24;
-+ break;
-+ case COLOR_DEPTH_121212:
-+ params.ulPixelClock =
-+ (params.ulPixelClock * 36) / 24;
-+ break;
-+ case COLOR_DEPTH_161616:
-+ params.ulPixelClock =
-+ (params.ulPixelClock * 48) / 24;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params))
-+ result = BP_RESULT_OK;
-+
-+ return result;
-+}
-+#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 85a5924..a27db8c 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
-@@ -55,6 +55,12 @@ bool dal_bios_parser_init_cmd_tbl_helper(
- return true;
- #endif
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ case DCE_VERSION_11_2:
-+ *h = dal_cmd_tbl_helper_dce112_get_table();
-+ return true;
-+#endif
-+
- default:
- /* Unsupported DCE */
- BREAK_TO_DEBUGGER();
-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 a462917..e6a0d19 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
-@@ -32,6 +32,9 @@
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0) || defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- #include "dce110/command_table_helper_dce110.h"
- #endif
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+#include "dce112/command_table_helper_dce112.h"
-+#endif
-
- struct command_table_helper {
- bool (*controller_id_to_atom)(enum controller_id id, uint8_t *atom_id);
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/dce112/bios_parser_helper_dce112.c b/drivers/gpu/drm/amd/dal/dc/bios/dce112/bios_parser_helper_dce112.c
-new file mode 100644
-index 0000000..1b0f816
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/dce112/bios_parser_helper_dce112.c
-@@ -0,0 +1,480 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and 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 "include/bios_parser_types.h"
-+#include "include/adapter_service_types.h"
-+#include "include/logger_interface.h"
-+
-+#include "../bios_parser_helper.h"
-+
-+#include "dce/dce_11_0_d.h"
-+#include "bif/bif_5_1_d.h"
-+
-+/**
-+ * set_scratch_acc_mode_change
-+ *
-+ * @brief
-+ * set Accelerated Mode in VBIOS scratch register, VBIOS will clean it when
-+ * VGA/non-Accelerated mode is set
-+ *
-+ * @param
-+ * struct dc_context *ctx - [in] DAL context
-+ */
-+static void set_scratch_acc_mode_change(
-+ struct dc_context *ctx)
-+{
-+ uint32_t addr = mmBIOS_SCRATCH_6;
-+ uint32_t value = 0;
-+
-+ value = dm_read_reg(ctx, addr);
-+
-+ value |= ATOM_S6_ACC_MODE;
-+
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+/*
-+ * set_scratch_active_and_requested
-+ *
-+ * @brief
-+ * Set VBIOS scratch pad registers about active and requested displays
-+ *
-+ * @param
-+ * struct dc_context *ctx - [in] DAL context for register accessing
-+ * struct vbios_helper_data *d - [in] values to write
-+ */
-+static void set_scratch_active_and_requested(
-+ struct dc_context *ctx,
-+ struct vbios_helper_data *d)
-+{
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+
-+ /* mmBIOS_SCRATCH_3 = mmBIOS_SCRATCH_0 + ATOM_ACTIVE_INFO_DEF */
-+ addr = mmBIOS_SCRATCH_3;
-+
-+ value = 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;
-+}
-+
-+/**
-+ * get LCD Scale Mode from VBIOS scratch register
-+ */
-+static enum lcd_scale get_scratch_lcd_scale(
-+ struct dc_context *ctx)
-+{
-+ uint32_t addr = mmBIOS_SCRATCH_6;
-+ uint32_t value = 0;
-+
-+ value = 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;
-+}
-+
-+/**
-+ * prepare_scratch_active_and_requested
-+ *
-+ * @brief
-+ * prepare and update VBIOS scratch pad registers about active and requested
-+ * displays
-+ *
-+ * @param
-+ * data - helper's shared data
-+ * enum controller_ild - controller Id
-+ * enum signal_type - signal type used on display
-+ * const struct connector_device_tag_info* - pointer to display type and enum id
-+ */
-+static void prepare_scratch_active_and_requested(
-+ struct dc_context *ctx,
-+ struct vbios_helper_data *data,
-+ enum controller_id id,
-+ enum signal_type s,
-+ const struct connector_device_tag_info *dev_tag)
-+{
-+ switch (s) {
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
-+ case SIGNAL_TYPE_DVI_DUAL_LINK:
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ if (dev_tag->dev_id.device_type == DEVICE_TYPE_DFP)
-+ switch (dev_tag->dev_id.enum_id) {
-+ case 1:
-+ data->requested |= ATOM_S6_ACC_REQ_DFP1;
-+ data->active |= ATOM_S3_DFP1_ACTIVE;
-+ break;
-+ case 2:
-+ data->requested |= ATOM_S6_ACC_REQ_DFP2;
-+ data->active |= ATOM_S3_DFP2_ACTIVE;
-+ break;
-+ case 3:
-+ data->requested |= ATOM_S6_ACC_REQ_DFP3;
-+ data->active |= ATOM_S3_DFP3_ACTIVE;
-+ break;
-+ case 4:
-+ data->requested |= ATOM_S6_ACC_REQ_DFP4;
-+ data->active |= ATOM_S3_DFP4_ACTIVE;
-+ break;
-+ case 5:
-+ data->requested |= ATOM_S6_ACC_REQ_DFP5;
-+ data->active |= ATOM_S3_DFP5_ACTIVE;
-+ break;
-+ case 6:
-+ data->requested |= ATOM_S6_ACC_REQ_DFP6;
-+ data->active |= ATOM_S3_DFP6_ACTIVE;
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+ case SIGNAL_TYPE_LVDS:
-+ case SIGNAL_TYPE_EDP:
-+ data->requested |= ATOM_S6_ACC_REQ_LCD1;
-+ data->active |= ATOM_S3_LCD1_ACTIVE;
-+ break;
-+ case SIGNAL_TYPE_RGB:
-+ if (dev_tag->dev_id.device_type == DEVICE_TYPE_CRT)
-+ switch (dev_tag->dev_id.enum_id) {
-+ case 1:
-+ data->requested |= ATOM_S6_ACC_REQ_CRT1;
-+ data->active |= ATOM_S3_CRT1_ACTIVE;
-+ break;
-+ case 2:
-+ dal_logger_write(ctx->logger,
-+ LOG_MAJOR_BIOS,
-+ LOG_MINOR_COMPONENT_BIOS,
-+ "%s: DAL does not support DAC2!\n",
-+ __func__);
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+ default:
-+ dal_logger_write(ctx->logger,
-+ LOG_MAJOR_BIOS,
-+ LOG_MINOR_COMPONENT_BIOS,
-+ "%s: No such signal!\n",
-+ __func__);
-+ break;
-+ }
-+}
-+
-+/*
-+ * is_accelerated_mode
-+ *
-+ * @brief
-+ * set Accelerated Mode in VBIOS scratch register, VBIOS will clean it when
-+ * VGA/non-Accelerated mode is set
-+ *
-+ * @param
-+ * struct dc_context *ctx
-+ *
-+ * @return
-+ * true if in acceleration mode, false otherwise.
-+ */
-+static bool is_accelerated_mode(
-+ struct dc_context *ctx)
-+{
-+ uint32_t addr = mmBIOS_SCRATCH_6;
-+ uint32_t value = dm_read_reg(ctx, addr);
-+
-+ return (value & ATOM_S6_ACC_MODE) ? true : false;
-+}
-+
-+#define BIOS_SCRATCH0_DAC_B_SHIFT 8
-+
-+/**
-+ * detect_sink
-+ *
-+ * @brief
-+ * read VBIOS scratch register to determine whether display for the specified
-+ * signal is present and return the actual sink signal type
-+ * For analog signals VBIOS load detection has to be called prior reading the
-+ * register
-+ *
-+ * @param
-+ * encoder - encoder id (to specify DAC)
-+ * connector - connector id (to check CV on DIN)
-+ * signal - signal (as display type) to check
-+ *
-+ * @return
-+ * signal_type - actual (on the sink) signal type detected
-+ */
-+static enum signal_type detect_sink(
-+ struct dc_context *ctx,
-+ struct graphics_object_id encoder,
-+ struct graphics_object_id connector,
-+ enum signal_type signal)
-+{
-+ uint32_t bios_scratch0;
-+ uint32_t encoder_id = encoder.id;
-+ /* after DCE 10.x does not support DAC2, so assert and return SIGNAL_TYPE_NONE */
-+ if (encoder_id == ENCODER_ID_INTERNAL_DAC2
-+ || encoder_id == ENCODER_ID_INTERNAL_KLDSCP_DAC2) {
-+ ASSERT(false);
-+ return SIGNAL_TYPE_NONE;
-+ }
-+
-+ bios_scratch0 = 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) {
-+ bios_scratch0 <<= BIOS_SCRATCH0_DAC_B_SHIFT;
-+ }
-+
-+ switch (signal) {
-+ case SIGNAL_TYPE_RGB: {
-+ if (bios_scratch0 & ATOM_S0_CRT2_MASK)
-+ return SIGNAL_TYPE_RGB;
-+ break;
-+ }
-+ case SIGNAL_TYPE_LVDS: {
-+ if (bios_scratch0 & ATOM_S0_LCD1)
-+ return SIGNAL_TYPE_LVDS;
-+ break;
-+ }
-+ case SIGNAL_TYPE_EDP: {
-+ if (bios_scratch0 & ATOM_S0_LCD1)
-+ return SIGNAL_TYPE_EDP;
-+ break;
-+ }
-+ default:
-+ break;
-+ }
-+
-+ return SIGNAL_TYPE_NONE;
-+}
-+
-+/**
-+ * set_scratch_connected
-+ *
-+ * @brief
-+ * update BIOS_SCRATCH_0 register about connected displays
-+ *
-+ * @param
-+ * bool - update scratch register or just prepare info to be updated
-+ * bool - connection state
-+ * const struct connector_device_tag_info * - pointer to device type and enum ID
-+ */
-+static void set_scratch_connected(
-+ struct dc_context *ctx,
-+ struct graphics_object_id id,
-+ bool connected,
-+ const struct connector_device_tag_info *device_tag)
-+{
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+ uint32_t update = 0;
-+
-+ switch (device_tag->dev_id.device_type) {
-+ case DEVICE_TYPE_LCD:
-+ /* For LCD VBIOS will update LCD Panel connected bit always and
-+ * Lid state bit based on SBIOS info do not do anything here
-+ * for LCD
-+ */
-+ break;
-+ case DEVICE_TYPE_CRT:
-+ /* CRT is not supported in DCE11 */
-+ break;
-+ case DEVICE_TYPE_DFP:
-+ switch (device_tag->dev_id.enum_id) {
-+ case 1:
-+ update |= ATOM_S0_DFP1;
-+ break;
-+ case 2:
-+ update |= ATOM_S0_DFP2;
-+ break;
-+ case 3:
-+ update |= ATOM_S0_DFP3;
-+ break;
-+ case 4:
-+ update |= ATOM_S0_DFP4;
-+ break;
-+ case 5:
-+ update |= ATOM_S0_DFP5;
-+ break;
-+ case 6:
-+ update |= ATOM_S0_DFP6;
-+ break;
-+ default:
-+ break;
-+ }
-+ break;
-+ case DEVICE_TYPE_CV:
-+ /* DCE 8.0 does not support CV, so don't do anything */
-+ break;
-+
-+ case DEVICE_TYPE_TV:
-+ /* For TV VBIOS will update S-Video or
-+ * Composite scratch bits on DAL_LoadDetect
-+ * when called by driver, do not do anything
-+ * here for TV
-+ */
-+ break;
-+
-+ default:
-+ break;
-+
-+ }
-+
-+ /* update scratch register */
-+ addr = mmBIOS_SCRATCH_0 + ATOM_DEVICE_CONNECT_INFO_DEF;
-+
-+ value = dm_read_reg(ctx, addr);
-+
-+ if (connected)
-+ value |= update;
-+ else
-+ value &= ~update;
-+
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+static void set_scratch_critical_state(
-+ struct dc_context *ctx,
-+ bool state)
-+{
-+ uint32_t addr = mmBIOS_SCRATCH_6;
-+ uint32_t value = dm_read_reg(ctx, addr);
-+
-+ if (state)
-+ value |= ATOM_S6_CRITICAL_STATE;
-+ else
-+ value &= ~ATOM_S6_CRITICAL_STATE;
-+
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+static void set_scratch_lcd_scale(
-+ struct dc_context *ctx,
-+ enum lcd_scale lcd_scale_request)
-+{
-+ DAL_LOGGER_NOT_IMPL(
-+ LOG_MINOR_COMPONENT_BIOS,
-+ "Bios Parser:%s\n",
-+ __func__);
-+}
-+
-+static bool is_lid_open(struct dc_context *ctx)
-+{
-+ uint32_t bios_scratch6;
-+
-+ bios_scratch6 =
-+ dm_read_reg(
-+ ctx,
-+ mmBIOS_SCRATCH_0 + ATOM_ACC_CHANGE_INFO_DEF);
-+
-+ /* lid is open if the bit is not set */
-+ if (!(bios_scratch6 & ATOM_S6_LID_STATE))
-+ return true;
-+
-+ return false;
-+}
-+
-+/* function table */
-+static const struct bios_parser_helper bios_parser_helper_funcs = {
-+ .detect_sink = detect_sink,
-+ .fmt_bit_depth_control = NULL,
-+ .fmt_control = NULL,
-+ .get_bios_event_info = NULL,
-+ .get_embedded_display_controller_id = NULL,
-+ .get_embedded_display_refresh_rate = NULL,
-+ .get_requested_backlight_level = NULL,
-+ .get_scratch_lcd_scale = get_scratch_lcd_scale,
-+ .is_accelerated_mode = is_accelerated_mode,
-+ .is_active_display = NULL,
-+ .is_display_config_changed = NULL,
-+ .is_lid_open = is_lid_open,
-+ .is_lid_status_changed = NULL,
-+ .prepare_scratch_active_and_requested =
-+ prepare_scratch_active_and_requested,
-+ .set_scratch_acc_mode_change = set_scratch_acc_mode_change,
-+ .set_scratch_active_and_requested = set_scratch_active_and_requested,
-+ .set_scratch_connected = set_scratch_connected,
-+ .set_scratch_critical_state = set_scratch_critical_state,
-+ .set_scratch_lcd_scale = set_scratch_lcd_scale,
-+ .take_backlight_control = NULL,
-+ .update_requested_backlight_level = NULL,
-+};
-+
-+/*
-+ * dal_bios_parser_dce112_init_bios_helper
-+ *
-+ * @brief
-+ * Initialize BIOS helper functions
-+ *
-+ * @param
-+ * const struct command_table_helper **h - [out] struct of functions
-+ *
-+ */
-+
-+const struct bios_parser_helper *dal_bios_parser_helper_dce112_get_table()
-+{
-+ return &bios_parser_helper_funcs;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/dce112/bios_parser_helper_dce112.h b/drivers/gpu/drm/amd/dal/dc/bios/dce112/bios_parser_helper_dce112.h
-new file mode 100644
-index 0000000..044327e
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/dce112/bios_parser_helper_dce112.h
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_BIOS_PARSER_HELPER_DCE112_H__
-+#define __DAL_BIOS_PARSER_HELPER_DCE112_H__
-+
-+struct bios_parser_helper;
-+
-+/* Initialize BIOS helper functions */
-+const struct bios_parser_helper *dal_bios_parser_helper_dce112_get_table(void);
-+
-+#endif /* __DAL_BIOS_PARSER_HELPER_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/dce112/command_table_helper_dce112.c b/drivers/gpu/drm/amd/dal/dc/bios/dce112/command_table_helper_dce112.c
-new file mode 100644
-index 0000000..32ec228
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/dce112/command_table_helper_dce112.c
-@@ -0,0 +1,417 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 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/bios_parser_types.h"
-+#include "include/adapter_service_types.h"
-+
-+#include "../command_table_helper.h"
-+
-+static uint8_t phy_id_to_atom(enum transmitter t)
-+{
-+ uint8_t atom_phy_id;
-+
-+ switch (t) {
-+ case TRANSMITTER_UNIPHY_A:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYA;
-+ break;
-+ case TRANSMITTER_UNIPHY_B:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYB;
-+ break;
-+ case TRANSMITTER_UNIPHY_C:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYC;
-+ break;
-+ case TRANSMITTER_UNIPHY_D:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYD;
-+ break;
-+ case TRANSMITTER_UNIPHY_E:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYE;
-+ break;
-+ case TRANSMITTER_UNIPHY_F:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYF;
-+ break;
-+ case TRANSMITTER_UNIPHY_G:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYG;
-+ break;
-+ default:
-+ atom_phy_id = ATOM_PHY_ID_UNIPHYA;
-+ break;
-+ }
-+ return atom_phy_id;
-+}
-+
-+static uint8_t signal_type_to_atom_dig_mode(enum signal_type s)
-+{
-+ uint8_t atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP;
-+
-+ switch (s) {
-+ case SIGNAL_TYPE_DISPLAY_PORT:
-+ case SIGNAL_TYPE_EDP:
-+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP;
-+ break;
-+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
-+ case SIGNAL_TYPE_DVI_DUAL_LINK:
-+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DVI;
-+ break;
-+ case SIGNAL_TYPE_HDMI_TYPE_A:
-+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_HDMI;
-+ break;
-+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
-+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DP_MST;
-+ break;
-+ default:
-+ atom_dig_mode = ATOM_TRANSMITTER_DIGMODE_V6_DVI;
-+ break;
-+ }
-+
-+ return atom_dig_mode;
-+}
-+
-+static uint8_t clock_source_id_to_atom_phy_clk_src_id(
-+ enum clock_source_id id)
-+{
-+ uint8_t atom_phy_clk_src_id = 0;
-+
-+ switch (id) {
-+ case CLOCK_SOURCE_ID_PLL0:
-+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P0PLL;
-+ break;
-+ case CLOCK_SOURCE_ID_PLL1:
-+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
-+ break;
-+ case CLOCK_SOURCE_ID_PLL2:
-+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P2PLL;
-+ break;
-+ case CLOCK_SOURCE_ID_EXTERNAL:
-+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_REFCLK_SRC_EXT;
-+ break;
-+ default:
-+ atom_phy_clk_src_id = ATOM_TRANSMITTER_CONFIG_V5_P1PLL;
-+ break;
-+ }
-+
-+ return atom_phy_clk_src_id >> 2;
-+}
-+
-+static uint8_t hpd_sel_to_atom(enum hpd_source_id id)
-+{
-+ uint8_t atom_hpd_sel = 0;
-+
-+ switch (id) {
-+ case HPD_SOURCEID1:
-+ atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD1_SEL;
-+ break;
-+ case HPD_SOURCEID2:
-+ atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD2_SEL;
-+ break;
-+ case HPD_SOURCEID3:
-+ atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD3_SEL;
-+ break;
-+ case HPD_SOURCEID4:
-+ atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD4_SEL;
-+ break;
-+ case HPD_SOURCEID5:
-+ atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD5_SEL;
-+ break;
-+ case HPD_SOURCEID6:
-+ atom_hpd_sel = ATOM_TRANSMITTER_V6_HPD6_SEL;
-+ break;
-+ case HPD_SOURCEID_UNKNOWN:
-+ default:
-+ atom_hpd_sel = 0;
-+ break;
-+ }
-+ return atom_hpd_sel;
-+}
-+
-+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_V6__DIGA_SEL;
-+ break;
-+ case ENGINE_ID_DIGB:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGB_SEL;
-+ break;
-+ case ENGINE_ID_DIGC:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGC_SEL;
-+ break;
-+ case ENGINE_ID_DIGD:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGD_SEL;
-+ break;
-+ case ENGINE_ID_DIGE:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGE_SEL;
-+ break;
-+ case ENGINE_ID_DIGF:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGF_SEL;
-+ break;
-+ case ENGINE_ID_DIGG:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGG_SEL;
-+ break;
-+ case ENGINE_ID_UNKNOWN:
-+ /* No DIG_FRONT is associated to DIG_BACKEND */
-+ atom_dig_encoder_sel = 0;
-+ break;
-+ default:
-+ atom_dig_encoder_sel = ATOM_TRANMSITTER_V6__DIGA_SEL;
-+ break;
-+ }
-+
-+ return atom_dig_encoder_sel;
-+}
-+
-+static bool clock_source_id_to_atom(
-+ enum clock_source_id id,
-+ uint32_t *atom_pll_id)
-+{
-+ bool result = true;
-+
-+ if (atom_pll_id != NULL)
-+ switch (id) {
-+ case CLOCK_SOURCE_COMBO_PHY_PLL0:
-+ *atom_pll_id = ATOM_COMBOPHY_PLL0;
-+ break;
-+ case CLOCK_SOURCE_COMBO_PHY_PLL1:
-+ *atom_pll_id = ATOM_COMBOPHY_PLL1;
-+ break;
-+ case CLOCK_SOURCE_COMBO_PHY_PLL2:
-+ *atom_pll_id = ATOM_COMBOPHY_PLL2;
-+ break;
-+ case CLOCK_SOURCE_COMBO_PHY_PLL3:
-+ *atom_pll_id = ATOM_COMBOPHY_PLL3;
-+ break;
-+ case CLOCK_SOURCE_COMBO_PHY_PLL4:
-+ *atom_pll_id = ATOM_COMBOPHY_PLL4;
-+ break;
-+ case CLOCK_SOURCE_COMBO_PHY_PLL5:
-+ *atom_pll_id = ATOM_COMBOPHY_PLL5;
-+ break;
-+ case CLOCK_SOURCE_COMBO_DISPLAY_PLL0:
-+ *atom_pll_id = ATOM_PPLL0;
-+ break;
-+ case CLOCK_SOURCE_ID_DFS:
-+ *atom_pll_id = ATOM_GCK_DFS;
-+ break;
-+ case CLOCK_SOURCE_ID_VCE:
-+ *atom_pll_id = ATOM_DP_DTO;
-+ break;
-+ case CLOCK_SOURCE_ID_DP_DTO:
-+ *atom_pll_id = ATOM_DP_DTO;
-+ break;
-+ case CLOCK_SOURCE_ID_UNDEFINED:
-+ /* Should not happen */
-+ *atom_pll_id = ATOM_PPLL_INVALID;
-+ result = false;
-+ break;
-+ default:
-+ result = false;
-+ break;
-+ }
-+
-+ return result;
-+}
-+
-+static bool engine_bp_to_atom(enum engine_id id, uint32_t *atom_engine_id)
-+{
-+ bool result = false;
-+
-+ if (atom_engine_id != NULL)
-+ switch (id) {
-+ case ENGINE_ID_DIGA:
-+ *atom_engine_id = ASIC_INT_DIG1_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DIGB:
-+ *atom_engine_id = ASIC_INT_DIG2_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DIGC:
-+ *atom_engine_id = ASIC_INT_DIG3_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DIGD:
-+ *atom_engine_id = ASIC_INT_DIG4_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DIGE:
-+ *atom_engine_id = ASIC_INT_DIG5_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DIGF:
-+ *atom_engine_id = ASIC_INT_DIG6_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DIGG:
-+ *atom_engine_id = ASIC_INT_DIG7_ENCODER_ID;
-+ result = true;
-+ break;
-+ case ENGINE_ID_DACA:
-+ *atom_engine_id = ASIC_INT_DAC1_ENCODER_ID;
-+ result = true;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return result;
-+}
-+
-+static uint8_t encoder_action_to_atom(enum bp_encoder_control_action action)
-+{
-+ uint8_t atom_action = 0;
-+
-+ switch (action) {
-+ case ENCODER_CONTROL_ENABLE:
-+ atom_action = ATOM_ENABLE;
-+ break;
-+ case ENCODER_CONTROL_DISABLE:
-+ atom_action = ATOM_DISABLE;
-+ break;
-+ case ENCODER_CONTROL_SETUP:
-+ atom_action = ATOM_ENCODER_CMD_STREAM_SETUP;
-+ break;
-+ case ENCODER_CONTROL_INIT:
-+ atom_action = ATOM_ENCODER_INIT;
-+ break;
-+ default:
-+ BREAK_TO_DEBUGGER(); /* Unhandle action in driver.!! */
-+ break;
-+ }
-+
-+ return atom_action;
-+}
-+
-+static uint8_t disp_power_gating_action_to_atom(
-+ enum bp_pipe_control_action action)
-+{
-+ uint8_t atom_pipe_action = 0;
-+
-+ switch (action) {
-+ case ASIC_PIPE_DISABLE:
-+ atom_pipe_action = ATOM_DISABLE;
-+ break;
-+ case ASIC_PIPE_ENABLE:
-+ atom_pipe_action = ATOM_ENABLE;
-+ break;
-+ case ASIC_PIPE_INIT:
-+ atom_pipe_action = ATOM_INIT;
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false); /* Unhandle action in driver! */
-+ break;
-+ }
-+
-+ return atom_pipe_action;
-+}
-+
-+bool dc_clock_type_to_atom(enum bp_dce_clock_type id, uint32_t *atom_clock_type)
-+{
-+ bool retCode = true;
-+
-+ if (atom_clock_type != NULL) {
-+ switch (id) {
-+ case DCECLOCK_TYPE_DISPLAY_CLOCK:
-+ *atom_clock_type = DCE_CLOCK_TYPE_DISPCLK;
-+ break;
-+
-+ case DCECLOCK_TYPE_DPREFCLK:
-+ *atom_clock_type = DCE_CLOCK_TYPE_DPREFCLK;
-+ break;
-+
-+ default:
-+ ASSERT_CRITICAL(false); /* Unhandle action in driver! */
-+ break;
-+ }
-+ }
-+
-+ return retCode;
-+}
-+
-+uint8_t transmitter_color_depth_to_atom(enum transmitter_color_depth id)
-+{
-+ uint8_t atomColorDepth = 0;
-+
-+ switch (id) {
-+ case TRANSMITTER_COLOR_DEPTH_24:
-+ atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_DIS;
-+ break;
-+ case TRANSMITTER_COLOR_DEPTH_30:
-+ atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_5_4;
-+ break;
-+ case TRANSMITTER_COLOR_DEPTH_36:
-+ atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_3_2;
-+ break;
-+ case TRANSMITTER_COLOR_DEPTH_48:
-+ atomColorDepth = PIXEL_CLOCK_V7_DEEPCOLOR_RATIO_2_1;
-+ break;
-+ default:
-+ ASSERT_CRITICAL(false); /* Unhandle action in driver! */
-+ break;
-+ }
-+
-+ return atomColorDepth;
-+}
-+
-+/* function table */
-+static const struct command_table_helper command_table_helper_funcs = {
-+ .controller_id_to_atom = dal_cmd_table_helper_controller_id_to_atom,
-+ .encoder_action_to_atom = encoder_action_to_atom,
-+ .engine_bp_to_atom = engine_bp_to_atom,
-+ .clock_source_id_to_atom = clock_source_id_to_atom,
-+ .clock_source_id_to_atom_phy_clk_src_id =
-+ clock_source_id_to_atom_phy_clk_src_id,
-+ .signal_type_to_atom_dig_mode = signal_type_to_atom_dig_mode,
-+ .hpd_sel_to_atom = hpd_sel_to_atom,
-+ .dig_encoder_sel_to_atom = dig_encoder_sel_to_atom,
-+ .phy_id_to_atom = phy_id_to_atom,
-+ .disp_power_gating_action_to_atom = disp_power_gating_action_to_atom,
-+ .assign_control_parameter = NULL,
-+ .clock_source_id_to_ref_clk_src = NULL,
-+ .transmitter_bp_to_atom = NULL,
-+ .encoder_id_to_atom = dal_cmd_table_helper_encoder_id_to_atom,
-+ .encoder_mode_bp_to_atom = dal_cmd_table_helper_encoder_mode_bp_to_atom,
-+ .dc_clock_type_to_atom = dc_clock_type_to_atom,
-+ .transmitter_color_depth_to_atom = transmitter_color_depth_to_atom,
-+};
-+
-+/*
-+ * dal_cmd_tbl_helper_dce110_get_table
-+ *
-+ * @brief
-+ * Initialize command table helper functions
-+ *
-+ * @param
-+ * const struct command_table_helper **h - [out] struct of functions
-+ *
-+ */
-+const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table()
-+{
-+ return &command_table_helper_funcs;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/bios/dce112/command_table_helper_dce112.h b/drivers/gpu/drm/amd/dal/dc/bios/dce112/command_table_helper_dce112.h
-new file mode 100644
-index 0000000..dc36609
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/bios/dce112/command_table_helper_dce112.h
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_COMMAND_TABLE_HELPER_DCE112_H__
-+#define __DAL_COMMAND_TABLE_HELPER_DCE112_H__
-+
-+struct command_table_helper;
-+
-+/* Initialize command table helper functions */
-+const struct command_table_helper *dal_cmd_tbl_helper_dce112_get_table(void);
-+
-+#endif /* __DAL_COMMAND_TABLE_HELPER_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c b/drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c
-index f39499a..8a19139 100644
---- a/drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c
-+++ b/drivers/gpu/drm/amd/dal/dc/calcs/bandwidth_calcs.c
-@@ -3726,6 +3726,212 @@ void bw_calcs_init(struct bw_calcs_dceip *bw_dceip,
- dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
- dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0); /* todo: this is a bug*/
- break;
-+ case BW_CALCS_VERSION_ELLESMERE:
-+ vbios.number_of_dram_channels = 8;
-+ vbios.dram_channel_width_in_bits = 32;
-+ vbios.number_of_dram_banks = 8;
-+ vbios.high_yclk = bw_int_to_fixed(6000);
-+ vbios.mid_yclk = bw_int_to_fixed(3200);
-+ vbios.low_yclk = bw_int_to_fixed(1000);
-+ vbios.low_sclk = bw_int_to_fixed(300);
-+ vbios.mid_sclk = bw_int_to_fixed(974);
-+ vbios.high_sclk = bw_int_to_fixed(1154);
-+ vbios.low_voltage_max_dispclk = bw_int_to_fixed(459);
-+ vbios.mid_voltage_max_dispclk = bw_int_to_fixed(654);
-+ vbios.high_voltage_max_dispclk = bw_int_to_fixed(1132);
-+ vbios.data_return_bus_width = bw_int_to_fixed(32);
-+ vbios.trc = bw_int_to_fixed(48);
-+ vbios.dmifmc_urgent_latency = bw_int_to_fixed(3);
-+ vbios.stutter_self_refresh_exit_latency = bw_int_to_fixed(5);
-+ vbios.nbp_state_change_latency = bw_int_to_fixed(45);
-+ vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
-+ vbios.scatter_gather_enable = true;
-+ vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
-+ vbios.cursor_width = 32;
-+ vbios.average_compression_rate = 4;
-+ vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel =
-+ 256;
-+ vbios.blackout_duration = bw_int_to_fixed(0); /* us */
-+ vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
-+
-+ dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
-+ dceip.de_tiling_buffer = bw_int_to_fixed(0);
-+ dceip.dcfclk_request_generation = 0;
-+ dceip.lines_interleaved_into_lb = 2;
-+ dceip.chunk_width = 256;
-+ dceip.number_of_graphics_pipes = 6;
-+ dceip.number_of_underlay_pipes = 0;
-+ dceip.display_write_back_supported = false;
-+ dceip.argb_compression_support = false;
-+ dceip.underlay_vscaler_efficiency6_bit_per_component =
-+ bw_frc_to_fixed(35556, 10000);
-+ dceip.underlay_vscaler_efficiency8_bit_per_component =
-+ bw_frc_to_fixed(34286, 10000);
-+ dceip.underlay_vscaler_efficiency10_bit_per_component =
-+ bw_frc_to_fixed(32, 10);
-+ dceip.underlay_vscaler_efficiency12_bit_per_component =
-+ bw_int_to_fixed(3);
-+ dceip.graphics_vscaler_efficiency6_bit_per_component =
-+ bw_frc_to_fixed(35, 10);
-+ dceip.graphics_vscaler_efficiency8_bit_per_component =
-+ bw_frc_to_fixed(34286, 10000);
-+ dceip.graphics_vscaler_efficiency10_bit_per_component =
-+ bw_frc_to_fixed(32, 10);
-+ dceip.graphics_vscaler_efficiency12_bit_per_component =
-+ bw_int_to_fixed(3);
-+ dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
-+ dceip.max_dmif_buffer_allocated = 4;
-+ dceip.graphics_dmif_size = 12288;
-+ dceip.underlay_luma_dmif_size = 19456;
-+ dceip.underlay_chroma_dmif_size = 23552;
-+ dceip.pre_downscaler_enabled = true;
-+ dceip.underlay_downscale_prefetch_enabled = true;
-+ dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
-+ dceip.lb_size_per_component444 = bw_int_to_fixed(245952);
-+ dceip.graphics_lb_nodownscaling_multi_line_prefetching = true;
-+ dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
-+ bw_int_to_fixed(1);
-+ dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
-+ 82176);
-+ dceip.underlay420_chroma_lb_size_per_component =
-+ bw_int_to_fixed(164352);
-+ dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
-+ 82176);
-+ dceip.cursor_chunk_width = bw_int_to_fixed(64);
-+ dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
-+ dceip.cursor_memory_interface_buffer_pixels = bw_int_to_fixed(
-+ 64);
-+ dceip.underlay_maximum_width_efficient_for_tiling =
-+ bw_int_to_fixed(1920);
-+ dceip.underlay_maximum_height_efficient_for_tiling =
-+ bw_int_to_fixed(1080);
-+ dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
-+ bw_frc_to_fixed(3, 10);
-+ dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
-+ bw_int_to_fixed(25);
-+ dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
-+ 2);
-+ dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
-+ bw_int_to_fixed(128);
-+ dceip.limit_excessive_outstanding_dmif_requests = true;
-+ dceip.linear_mode_line_request_alternation_slice =
-+ bw_int_to_fixed(64);
-+ dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
-+ 32;
-+ dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
-+ dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
-+ dceip.request_efficiency = bw_frc_to_fixed(8, 10);
-+ dceip.dispclk_per_request = bw_int_to_fixed(2);
-+ dceip.dispclk_ramping_factor = bw_frc_to_fixed(11, 10);
-+ dceip.display_pipe_throughput_factor = bw_frc_to_fixed(
-+ 105,
-+ 100);
-+ dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
-+ dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0);
-+ break;
-+ case BW_CALCS_VERSION_BAFFIN:
-+ vbios.number_of_dram_channels = 4;
-+ vbios.dram_channel_width_in_bits = 32;
-+ vbios.number_of_dram_banks = 8;
-+ vbios.high_yclk = bw_int_to_fixed(6000);
-+ vbios.mid_yclk = bw_int_to_fixed(3200);
-+ vbios.low_yclk = bw_int_to_fixed(1000);
-+ vbios.low_sclk = bw_int_to_fixed(300);
-+ vbios.mid_sclk = bw_int_to_fixed(974);
-+ vbios.high_sclk = bw_int_to_fixed(1154);
-+ vbios.low_voltage_max_dispclk = bw_int_to_fixed(459);
-+ vbios.mid_voltage_max_dispclk = bw_int_to_fixed(654);
-+ vbios.high_voltage_max_dispclk = bw_int_to_fixed(1132);
-+ vbios.data_return_bus_width = bw_int_to_fixed(32);
-+ vbios.trc = bw_int_to_fixed(48);
-+ vbios.dmifmc_urgent_latency = bw_int_to_fixed(3);
-+ vbios.stutter_self_refresh_exit_latency = bw_int_to_fixed(5);
-+ vbios.nbp_state_change_latency = bw_int_to_fixed(45);
-+ vbios.mcifwrmc_urgent_latency = bw_int_to_fixed(10);
-+ vbios.scatter_gather_enable = true;
-+ vbios.down_spread_percentage = bw_frc_to_fixed(5, 10);
-+ vbios.cursor_width = 32;
-+ vbios.average_compression_rate = 4;
-+ vbios.number_of_request_slots_gmc_reserves_for_dmif_per_channel =
-+ 256;
-+ vbios.blackout_duration = bw_int_to_fixed(0); /* us */
-+ vbios.maximum_blackout_recovery_time = bw_int_to_fixed(0);
-+
-+ dceip.dmif_request_buffer_size = bw_int_to_fixed(768);
-+ dceip.de_tiling_buffer = bw_int_to_fixed(0);
-+ dceip.dcfclk_request_generation = 0;
-+ dceip.lines_interleaved_into_lb = 2;
-+ dceip.chunk_width = 256;
-+ dceip.number_of_graphics_pipes = 5;
-+ dceip.number_of_underlay_pipes = 0;
-+ dceip.display_write_back_supported = false;
-+ dceip.argb_compression_support = false;
-+ dceip.underlay_vscaler_efficiency6_bit_per_component =
-+ bw_frc_to_fixed(35556, 10000);
-+ dceip.underlay_vscaler_efficiency8_bit_per_component =
-+ bw_frc_to_fixed(34286, 10000);
-+ dceip.underlay_vscaler_efficiency10_bit_per_component =
-+ bw_frc_to_fixed(32, 10);
-+ dceip.underlay_vscaler_efficiency12_bit_per_component =
-+ bw_int_to_fixed(3);
-+ dceip.graphics_vscaler_efficiency6_bit_per_component =
-+ bw_frc_to_fixed(35, 10);
-+ dceip.graphics_vscaler_efficiency8_bit_per_component =
-+ bw_frc_to_fixed(34286, 10000);
-+ dceip.graphics_vscaler_efficiency10_bit_per_component =
-+ bw_frc_to_fixed(32, 10);
-+ dceip.graphics_vscaler_efficiency12_bit_per_component =
-+ bw_int_to_fixed(3);
-+ dceip.alpha_vscaler_efficiency = bw_int_to_fixed(3);
-+ dceip.max_dmif_buffer_allocated = 4;
-+ dceip.graphics_dmif_size = 12288;
-+ dceip.underlay_luma_dmif_size = 19456;
-+ dceip.underlay_chroma_dmif_size = 23552;
-+ dceip.pre_downscaler_enabled = true;
-+ dceip.underlay_downscale_prefetch_enabled = true;
-+ dceip.lb_write_pixels_per_dispclk = bw_int_to_fixed(1);
-+ dceip.lb_size_per_component444 = bw_int_to_fixed(245952);
-+ dceip.graphics_lb_nodownscaling_multi_line_prefetching = true;
-+ dceip.stutter_and_dram_clock_state_change_gated_before_cursor =
-+ bw_int_to_fixed(1);
-+ dceip.underlay420_luma_lb_size_per_component = bw_int_to_fixed(
-+ 82176);
-+ dceip.underlay420_chroma_lb_size_per_component =
-+ bw_int_to_fixed(164352);
-+ dceip.underlay422_lb_size_per_component = bw_int_to_fixed(
-+ 82176);
-+ dceip.cursor_chunk_width = bw_int_to_fixed(64);
-+ dceip.cursor_dcp_buffer_lines = bw_int_to_fixed(4);
-+ dceip.cursor_memory_interface_buffer_pixels = bw_int_to_fixed(
-+ 64);
-+ dceip.underlay_maximum_width_efficient_for_tiling =
-+ bw_int_to_fixed(1920);
-+ dceip.underlay_maximum_height_efficient_for_tiling =
-+ bw_int_to_fixed(1080);
-+ dceip.peak_pte_request_to_eviction_ratio_limiting_multiple_displays_or_single_rotated_display =
-+ bw_frc_to_fixed(3, 10);
-+ dceip.peak_pte_request_to_eviction_ratio_limiting_single_display_no_rotation =
-+ bw_int_to_fixed(25);
-+ dceip.minimum_outstanding_pte_request_limit = bw_int_to_fixed(
-+ 2);
-+ dceip.maximum_total_outstanding_pte_requests_allowed_by_saw =
-+ bw_int_to_fixed(128);
-+ dceip.limit_excessive_outstanding_dmif_requests = true;
-+ dceip.linear_mode_line_request_alternation_slice =
-+ bw_int_to_fixed(64);
-+ dceip.scatter_gather_lines_of_pte_prefetching_in_linear_mode =
-+ 32;
-+ dceip.display_write_back420_luma_mcifwr_buffer_size = 12288;
-+ dceip.display_write_back420_chroma_mcifwr_buffer_size = 8192;
-+ dceip.request_efficiency = bw_frc_to_fixed(8, 10);
-+ dceip.dispclk_per_request = bw_int_to_fixed(2);
-+ dceip.dispclk_ramping_factor = bw_frc_to_fixed(11, 10);
-+ dceip.display_pipe_throughput_factor = bw_frc_to_fixed(
-+ 105,
-+ 100);
-+ dceip.scatter_gather_pte_request_rows_in_tiling_mode = 2;
-+ dceip.mcifwr_all_surfaces_burst_time = bw_int_to_fixed(0);
-+ break;
- default:
- break;
- }
-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 61bb67a..f9dd0d8 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
-@@ -34,6 +34,9 @@
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
- #include "dce110/dce110_hw_sequencer.h"
- #endif
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+#include "dce112/dce112_hw_sequencer.h"
-+#endif
-
- bool dc_construct_hw_sequencer(
- struct adapter_service *adapter_serv,
-@@ -55,6 +58,10 @@ bool dc_construct_hw_sequencer(
- case DCE_VERSION_11_0:
- return dce110_hw_sequencer_construct(dc);
- #endif
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ case DCE_VERSION_11_2:
-+ return dce112_hw_sequencer_construct(dc);
-+#endif
- default:
- break;
- }
-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 5f3b702..087670d 100644
---- a/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c
-+++ b/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c
-@@ -41,11 +41,13 @@
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
- #include "dce110/dce110_resource.h"
- #endif
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+#include "dce112/dce112_resource.h"
-+#endif
-
- enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
-- {
-+{
- enum dce_version dc_version = DCE_VERSION_UNKNOWN;
--
- switch (asic_id.chip_family) {
-
- #if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-@@ -68,6 +70,12 @@ enum dce_version resource_parse_asic_id(struct hw_asic_id asic_id)
- break;
- }
- #endif
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ if (ASIC_REV_IS_POLARIS10_P(asic_id.hw_internal_rev) ||
-+ ASIC_REV_IS_POLARIS11_M(asic_id.hw_internal_rev)) {
-+ dc_version = DCE_VERSION_11_2;
-+ }
-+#endif
- break;
- default:
- dc_version = DCE_VERSION_UNKNOWN;
-@@ -83,6 +91,11 @@ bool dc_construct_resource_pool(struct adapter_service *adapter_serv,
- {
-
- switch (dc_version) {
-+#if defined(CONFIG_DRM_AMD_DAL_DCE8_0)
-+ case DCE_VERSION_8_0:
-+ return dce80_construct_resource_pool(
-+ adapter_serv, num_virtual_links, dc, &dc->res_pool);
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- case DCE_VERSION_10_0:
- return dce100_construct_resource_pool(
-@@ -93,6 +106,11 @@ bool dc_construct_resource_pool(struct adapter_service *adapter_serv,
- return dce110_construct_resource_pool(
- adapter_serv, num_virtual_links, dc, &dc->res_pool);
- #endif
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ case DCE_VERSION_11_2:
-+ return dce112_construct_resource_pool(
-+ adapter_serv, num_virtual_links, dc, &dc->res_pool);
-+#endif
- default:
- break;
- }
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c
-index 3d4f8b7..a21fcbd 100644
---- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_hw_sequencer.c
-@@ -416,6 +416,7 @@ static void dce110_crtc_switch_to_clk_src(
- uint32_t pixel_rate_cntl_value;
- uint32_t addr;
-
-+ /* These addresses are the same across DCE8 - DCE11.2 */
- addr = mmCRTC0_PIXEL_RATE_CNTL + crtc_inst *
- (mmCRTC1_PIXEL_RATE_CNTL - mmCRTC0_PIXEL_RATE_CNTL);
-
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.c
-index de370ee..a9ef65d 100644
---- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.c
-+++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_timing_generator.c
-@@ -59,7 +59,7 @@ enum black_color_format {
-
- /* Flowing register offsets are same in files of
- * dce/dce_11_0_d.h
-- * dce/vi_ellesmere_p/vi_ellesmere_d.h
-+ * dce/vi_polaris10_p/vi_polaris10_d.h
- *
- * So we can create dce110 timing generator to use it.
- */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/Makefile b/drivers/gpu/drm/amd/dal/dc/dce112/Makefile
-new file mode 100644
-index 0000000..c7d61d9
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce112/Makefile
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the 'controller' sub-component of DAL.
-+# It provides the control and status of HW CRTC block.
-+
-+DCE112 = dce112_link_encoder.o dce112_compressor.o dce112_hw_sequencer.o \
-+dce112_resource.o dce112_clock_source.o dce112_mem_input.o
-+
-+AMD_DAL_DCE112 = $(addprefix $(AMDDALPATH)/dc/dce112/,$(DCE112))
-+
-+AMD_DAL_FILES += $(AMD_DAL_DCE112)
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.c b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.c
-new file mode 100644
-index 0000000..7ec9508
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.c
-@@ -0,0 +1,266 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dm_services.h"
-+
-+#include "dce112_clock_source.h"
-+
-+/* include DCE11.2 register header files */
-+#include "dce/dce_11_2_d.h"
-+#include "dce/dce_11_2_sh_mask.h"
-+
-+#include "dc_types.h"
-+#include "core_types.h"
-+
-+#include "include/grph_object_id.h"
-+#include "include/logger_interface.h"
-+
-+/**
-+ * Calculate PLL Dividers for given Clock Value.
-+ * First will call VBIOS Adjust Exec table to check if requested Pixel clock
-+ * will be Adjusted based on usage.
-+ * Then it will calculate PLL Dividers for this Adjusted clock using preferred
-+ * method (Maximum VCO frequency).
-+ *
-+ * \return
-+ * Calculation error in units of 0.01%
-+ */
-+static uint32_t dce112_get_pix_clk_dividers(
-+ struct clock_source *cs,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings)
-+{
-+ struct dce112_clk_src *clk_src = TO_DCE112_CLK_SRC(cs);
-+ uint32_t actualPixelClockInKHz;
-+
-+ if (pix_clk_params == NULL || pll_settings == NULL
-+ || pix_clk_params->requested_pix_clk == 0) {
-+ dal_logger_write(cs->ctx->logger,
-+ LOG_MAJOR_ERROR,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s: Invalid parameters!!\n", __func__);
-+ return 0;
-+ }
-+
-+ memset(pll_settings, 0, sizeof(*pll_settings));
-+
-+ if (clk_src->base.id == CLOCK_SOURCE_ID_DP_DTO) {
-+ pll_settings->adjusted_pix_clk = clk_src->ext_clk_khz;
-+ pll_settings->calculated_pix_clk = clk_src->ext_clk_khz;
-+ pll_settings->actual_pix_clk =
-+ pix_clk_params->requested_pix_clk;
-+ return 0;
-+ }
-+ /* PLL only after this point */
-+
-+ actualPixelClockInKHz = pix_clk_params->requested_pix_clk;
-+
-+ /* Calculate Dividers */
-+ if (pix_clk_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) {
-+ switch (pix_clk_params->color_depth) {
-+ case COLOR_DEPTH_101010:
-+ actualPixelClockInKHz = (actualPixelClockInKHz * 5) >> 2;
-+ break;
-+ case COLOR_DEPTH_121212:
-+ actualPixelClockInKHz = (actualPixelClockInKHz * 6) >> 2;
-+ break;
-+ case COLOR_DEPTH_161616:
-+ actualPixelClockInKHz = actualPixelClockInKHz * 2;
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ pll_settings->actual_pix_clk = actualPixelClockInKHz;
-+ pll_settings->adjusted_pix_clk = actualPixelClockInKHz;
-+ pll_settings->calculated_pix_clk = pix_clk_params->requested_pix_clk;
-+
-+ return 0;
-+}
-+
-+static void program_pixel_clk_resync(
-+ struct dce112_clk_src *clk_src,
-+ enum signal_type signal_type,
-+ enum dc_color_depth colordepth)
-+{
-+ uint32_t value = 0;
-+
-+ value = dm_read_reg(clk_src->base.ctx,
-+ clk_src->offsets.pixclk_resync_cntl);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ PHYPLLA_PIXCLK_RESYNC_CNTL,
-+ PHYPLLA_DCCG_DEEP_COLOR_CNTL);
-+
-+ /*
-+ 24 bit mode: TMDS clock = 1.0 x pixel clock (1:1)
-+ 30 bit mode: TMDS clock = 1.25 x pixel clock (5:4)
-+ 36 bit mode: TMDS clock = 1.5 x pixel clock (3:2)
-+ 48 bit mode: TMDS clock = 2 x pixel clock (2:1)
-+ */
-+ if (signal_type != SIGNAL_TYPE_HDMI_TYPE_A)
-+ return;
-+
-+ switch (colordepth) {
-+ case COLOR_DEPTH_888:
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ PHYPLLA_PIXCLK_RESYNC_CNTL,
-+ PHYPLLA_DCCG_DEEP_COLOR_CNTL);
-+ break;
-+ case COLOR_DEPTH_101010:
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ PHYPLLA_PIXCLK_RESYNC_CNTL,
-+ PHYPLLA_DCCG_DEEP_COLOR_CNTL);
-+ break;
-+ case COLOR_DEPTH_121212:
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ PHYPLLA_PIXCLK_RESYNC_CNTL,
-+ PHYPLLA_DCCG_DEEP_COLOR_CNTL);
-+ break;
-+ case COLOR_DEPTH_161616:
-+ set_reg_field_value(
-+ value,
-+ 3,
-+ PHYPLLA_PIXCLK_RESYNC_CNTL,
-+ PHYPLLA_DCCG_DEEP_COLOR_CNTL);
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ dm_write_reg(
-+ clk_src->base.ctx,
-+ clk_src->offsets.pixclk_resync_cntl,
-+ value);
-+}
-+
-+static bool dce112_program_pix_clk(
-+ struct clock_source *clk_src,
-+ struct pixel_clk_params *pix_clk_params,
-+ struct pll_settings *pll_settings)
-+{
-+ struct dce112_clk_src *dce112_clk_src = TO_DCE112_CLK_SRC(clk_src);
-+ struct bp_pixel_clock_parameters bp_pc_params = {0};
-+
-+ /*ATOMBIOS expects pixel rate adjusted by deep color ratio)*/
-+ bp_pc_params.controller_id = pix_clk_params->controller_id;
-+ bp_pc_params.pll_id = clk_src->id;
-+ bp_pc_params.target_pixel_clock = pll_settings->actual_pix_clk;
-+ bp_pc_params.encoder_object_id = pix_clk_params->encoder_object_id;
-+ bp_pc_params.signal_type = pix_clk_params->signal_type;
-+
-+ if (clk_src->id != CLOCK_SOURCE_ID_DP_DTO) {
-+ bp_pc_params.flags.SET_GENLOCK_REF_DIV_SRC =
-+ pll_settings->use_external_clk;
-+ bp_pc_params.flags.SET_XTALIN_REF_SRC =
-+ !pll_settings->use_external_clk;
-+ bp_pc_params.flags.SUPPORT_YUV_420 = 0;
-+ }
-+
-+ if (dce112_clk_src->bios->funcs->set_pixel_clock(
-+ dce112_clk_src->bios, &bp_pc_params) != BP_RESULT_OK)
-+ return false;
-+
-+ /* TODO: support YCBCR420 */
-+
-+ /* Resync deep color DTO */
-+ if (clk_src->id != CLOCK_SOURCE_ID_DP_DTO)
-+ program_pixel_clk_resync(dce112_clk_src,
-+ pix_clk_params->signal_type,
-+ pix_clk_params->color_depth);
-+
-+ return true;
-+}
-+
-+static bool dce112_clock_source_power_down(
-+ struct clock_source *clk_src)
-+{
-+ struct dce112_clk_src *dce112_clk_src = TO_DCE112_CLK_SRC(clk_src);
-+ enum bp_result bp_result;
-+ struct bp_pixel_clock_parameters bp_pixel_clock_params = {0};
-+
-+ if (clk_src->id == CLOCK_SOURCE_ID_DP_DTO)
-+ return true;
-+
-+ /* If Pixel Clock is 0 it means Power Down Pll*/
-+ bp_pixel_clock_params.controller_id = CONTROLLER_ID_UNDEFINED;
-+ bp_pixel_clock_params.pll_id = clk_src->id;
-+ bp_pixel_clock_params.flags.FORCE_PROGRAMMING_OF_PLL = 1;
-+
-+ /*Call ASICControl to process ATOMBIOS Exec table*/
-+ bp_result = dce112_clk_src->bios->funcs->set_pixel_clock(
-+ dce112_clk_src->bios,
-+ &bp_pixel_clock_params);
-+
-+ return bp_result == BP_RESULT_OK;
-+}
-+
-+/*****************************************/
-+/* Constructor */
-+/*****************************************/
-+static struct clock_source_funcs dce112_clk_src_funcs = {
-+ .cs_power_down = dce112_clock_source_power_down,
-+ .program_pix_clk = dce112_program_pix_clk,
-+ .get_pix_clk_dividers = dce112_get_pix_clk_dividers
-+};
-+
-+bool dce112_clk_src_construct(
-+ struct dce112_clk_src *clk_src,
-+ struct dc_context *ctx,
-+ struct dc_bios *bios,
-+ enum clock_source_id id,
-+ const struct dce112_clk_src_reg_offsets *reg_offsets)
-+{
-+ struct firmware_info fw_info = { { 0 } };
-+
-+ clk_src->base.ctx = ctx;
-+ clk_src->bios = bios;
-+ clk_src->base.id = id;
-+ clk_src->base.funcs = &dce112_clk_src_funcs;
-+ clk_src->offsets = *reg_offsets;
-+
-+ if (clk_src->bios->funcs->get_firmware_info(
-+ clk_src->bios, &fw_info) != BP_RESULT_OK) {
-+ ASSERT_CRITICAL(false);
-+ goto unexpected_failure;
-+ }
-+
-+ clk_src->ext_clk_khz = fw_info.external_clock_source_frequency_for_dp;
-+
-+ return true;
-+
-+unexpected_failure:
-+ return false;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.h b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.h
-new file mode 100644
-index 0000000..40ecc58
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_clock_source.h
-@@ -0,0 +1,52 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_CLOCK_SOURCE_DCE110_H__
-+#define __DC_CLOCK_SOURCE_DCE110_H__
-+
-+#include "clock_source.h"
-+
-+#define TO_DCE112_CLK_SRC(clk_src)\
-+ container_of(clk_src, struct dce112_clk_src, base)
-+
-+struct dce112_clk_src_reg_offsets {
-+ uint32_t pixclk_resync_cntl;
-+};
-+
-+struct dce112_clk_src {
-+ struct clock_source base;
-+ struct dce112_clk_src_reg_offsets offsets;
-+ struct dc_bios *bios;
-+
-+ uint32_t ext_clk_khz;
-+};
-+
-+bool dce112_clk_src_construct(
-+ struct dce112_clk_src *clk_src,
-+ struct dc_context *ctx,
-+ struct dc_bios *bios,
-+ enum clock_source_id,
-+ const struct dce112_clk_src_reg_offsets *reg_offsets);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_compressor.c b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_compressor.c
-new file mode 100644
-index 0000000..9526ffd
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_compressor.c
-@@ -0,0 +1,883 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dm_services.h"
-+
-+#include "dce/dce_11_2_d.h"
-+#include "dce/dce_11_2_sh_mask.h"
-+#include "gmc/gmc_8_1_sh_mask.h"
-+#include "gmc/gmc_8_1_d.h"
-+
-+#include "include/logger_interface.h"
-+#include "include/adapter_service_interface.h"
-+
-+#include "dce112_compressor.h"
-+
-+#define DCP_REG(reg)\
-+ (reg + cp110->offsets.dcp_offset)
-+#define DMIF_REG(reg)\
-+ (reg + cp110->offsets.dmif_offset)
-+
-+static const struct dce112_compressor_reg_offsets reg_offsets[] = {
-+{
-+ .dcp_offset = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif_offset =
-+ (mmDMIF_PG0_DPG_PIPE_DPM_CONTROL
-+ - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif_offset =
-+ (mmDMIF_PG1_DPG_PIPE_DPM_CONTROL
-+ - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+ .dmif_offset =
-+ (mmDMIF_PG2_DPG_PIPE_DPM_CONTROL
-+ - mmDMIF_PG0_DPG_PIPE_DPM_CONTROL),
-+}
-+};
-+
-+static const uint32_t dce11_one_lpt_channel_max_resolution = 2560 * 1600;
-+
-+enum fbc_idle_force {
-+ /* Bit 0 - Display registers updated */
-+ FBC_IDLE_FORCE_DISPLAY_REGISTER_UPDATE = 0x00000001,
-+
-+ /* Bit 2 - FBC_GRPH_COMP_EN register updated */
-+ FBC_IDLE_FORCE_GRPH_COMP_EN = 0x00000002,
-+ /* Bit 3 - FBC_SRC_SEL register updated */
-+ FBC_IDLE_FORCE_SRC_SEL_CHANGE = 0x00000004,
-+ /* Bit 4 - FBC_MIN_COMPRESSION register updated */
-+ FBC_IDLE_FORCE_MIN_COMPRESSION_CHANGE = 0x00000008,
-+ /* Bit 5 - FBC_ALPHA_COMP_EN register updated */
-+ FBC_IDLE_FORCE_ALPHA_COMP_EN = 0x00000010,
-+ /* Bit 6 - FBC_ZERO_ALPHA_CHUNK_SKIP_EN register updated */
-+ FBC_IDLE_FORCE_ZERO_ALPHA_CHUNK_SKIP_EN = 0x00000020,
-+ /* Bit 7 - FBC_FORCE_COPY_TO_COMP_BUF register updated */
-+ FBC_IDLE_FORCE_FORCE_COPY_TO_COMP_BUF = 0x00000040,
-+
-+ /* Bit 24 - Memory write to region 0 defined by MC registers. */
-+ FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION0 = 0x01000000,
-+ /* Bit 25 - Memory write to region 1 defined by MC registers */
-+ FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION1 = 0x02000000,
-+ /* Bit 26 - Memory write to region 2 defined by MC registers */
-+ FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION2 = 0x04000000,
-+ /* Bit 27 - Memory write to region 3 defined by MC registers. */
-+ FBC_IDLE_FORCE_MEMORY_WRITE_TO_REGION3 = 0x08000000,
-+
-+ /* Bit 28 - Memory write from any client other than MCIF */
-+ FBC_IDLE_FORCE_MEMORY_WRITE_OTHER_THAN_MCIF = 0x10000000,
-+ /* Bit 29 - CG statics screen signal is inactive */
-+ FBC_IDLE_FORCE_CG_STATIC_SCREEN_IS_INACTIVE = 0x20000000,
-+};
-+
-+static uint32_t lpt_size_alignment(struct dce112_compressor *cp110)
-+{
-+ /*LPT_ALIGNMENT (in bytes) = ROW_SIZE * #BANKS * # DRAM CHANNELS. */
-+ return cp110->base.raw_size * cp110->base.banks_num *
-+ cp110->base.dram_channels_num;
-+}
-+
-+static uint32_t lpt_memory_control_config(struct dce112_compressor *cp110,
-+ uint32_t lpt_control)
-+{
-+ /*LPT MC Config */
-+ if (cp110->base.options.bits.LPT_MC_CONFIG == 1) {
-+ /* POSSIBLE VALUES for LPT NUM_PIPES (DRAM CHANNELS):
-+ * 00 - 1 CHANNEL
-+ * 01 - 2 CHANNELS
-+ * 02 - 4 OR 6 CHANNELS
-+ * (Only for discrete GPU, N/A for CZ)
-+ * 03 - 8 OR 12 CHANNELS
-+ * (Only for discrete GPU, N/A for CZ) */
-+ switch (cp110->base.dram_channels_num) {
-+ case 2:
-+ set_reg_field_value(
-+ lpt_control,
-+ 1,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_NUM_PIPES);
-+ break;
-+ case 1:
-+ set_reg_field_value(
-+ lpt_control,
-+ 0,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_NUM_PIPES);
-+ break;
-+ default:
-+ dal_logger_write(
-+ cp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: Invalid LPT NUM_PIPES!!!",
-+ __func__);
-+ break;
-+ }
-+
-+ /* The mapping for LPT NUM_BANKS is in
-+ * GRPH_CONTROL.GRPH_NUM_BANKS register field
-+ * Specifies the number of memory banks for tiling
-+ * purposes. Only applies to 2D and 3D tiling modes.
-+ * POSSIBLE VALUES:
-+ * 00 - DCP_GRPH_NUM_BANKS_2BANK: ADDR_SURF_2_BANK
-+ * 01 - DCP_GRPH_NUM_BANKS_4BANK: ADDR_SURF_4_BANK
-+ * 02 - DCP_GRPH_NUM_BANKS_8BANK: ADDR_SURF_8_BANK
-+ * 03 - DCP_GRPH_NUM_BANKS_16BANK: ADDR_SURF_16_BANK */
-+ switch (cp110->base.banks_num) {
-+ case 16:
-+ set_reg_field_value(
-+ lpt_control,
-+ 3,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_NUM_BANKS);
-+ break;
-+ case 8:
-+ set_reg_field_value(
-+ lpt_control,
-+ 2,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_NUM_BANKS);
-+ break;
-+ case 4:
-+ set_reg_field_value(
-+ lpt_control,
-+ 1,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_NUM_BANKS);
-+ break;
-+ case 2:
-+ set_reg_field_value(
-+ lpt_control,
-+ 0,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_NUM_BANKS);
-+ break;
-+ default:
-+ dal_logger_write(
-+ cp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: Invalid LPT NUM_BANKS!!!",
-+ __func__);
-+ break;
-+ }
-+
-+ /* The mapping is in DMIF_ADDR_CALC.
-+ * ADDR_CONFIG_PIPE_INTERLEAVE_SIZE register field for
-+ * Carrizo specifies the memory interleave per pipe.
-+ * It effectively specifies the location of pipe bits in
-+ * the memory address.
-+ * POSSIBLE VALUES:
-+ * 00 - ADDR_CONFIG_PIPE_INTERLEAVE_256B: 256 byte
-+ * interleave
-+ * 01 - ADDR_CONFIG_PIPE_INTERLEAVE_512B: 512 byte
-+ * interleave
-+ */
-+ switch (cp110->base.channel_interleave_size) {
-+ case 256: /*256B */
-+ set_reg_field_value(
-+ lpt_control,
-+ 0,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_PIPE_INTERLEAVE_SIZE);
-+ break;
-+ case 512: /*512B */
-+ set_reg_field_value(
-+ lpt_control,
-+ 1,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_PIPE_INTERLEAVE_SIZE);
-+ break;
-+ default:
-+ dal_logger_write(
-+ cp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: Invalid LPT INTERLEAVE_SIZE!!!",
-+ __func__);
-+ break;
-+ }
-+
-+ /* The mapping for LOW_POWER_TILING_ROW_SIZE is in
-+ * DMIF_ADDR_CALC.ADDR_CONFIG_ROW_SIZE register field
-+ * for Carrizo. Specifies the size of dram row in bytes.
-+ * This should match up with NOOFCOLS field in
-+ * MC_ARB_RAMCFG (ROW_SIZE = 4 * 2 ^^ columns).
-+ * This register DMIF_ADDR_CALC is not used by the
-+ * hardware as it is only used for addrlib assertions.
-+ * POSSIBLE VALUES:
-+ * 00 - ADDR_CONFIG_1KB_ROW: Treat 1KB as DRAM row
-+ * boundary
-+ * 01 - ADDR_CONFIG_2KB_ROW: Treat 2KB as DRAM row
-+ * boundary
-+ * 02 - ADDR_CONFIG_4KB_ROW: Treat 4KB as DRAM row
-+ * boundary */
-+ switch (cp110->base.raw_size) {
-+ case 4096: /*4 KB */
-+ set_reg_field_value(
-+ lpt_control,
-+ 2,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ROW_SIZE);
-+ break;
-+ case 2048:
-+ set_reg_field_value(
-+ lpt_control,
-+ 1,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ROW_SIZE);
-+ break;
-+ case 1024:
-+ set_reg_field_value(
-+ lpt_control,
-+ 0,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ROW_SIZE);
-+ break;
-+ default:
-+ dal_logger_write(
-+ cp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: Invalid LPT ROW_SIZE!!!",
-+ __func__);
-+ break;
-+ }
-+ } else {
-+ dal_logger_write(
-+ cp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: LPT MC Configuration is not provided",
-+ __func__);
-+ }
-+
-+ return lpt_control;
-+}
-+
-+static bool is_source_bigger_than_epanel_size(
-+ struct dce112_compressor *cp110,
-+ uint32_t source_view_width,
-+ uint32_t source_view_height)
-+{
-+ if (cp110->base.embedded_panel_h_size != 0 &&
-+ cp110->base.embedded_panel_v_size != 0 &&
-+ ((source_view_width * source_view_height) >
-+ (cp110->base.embedded_panel_h_size *
-+ cp110->base.embedded_panel_v_size)))
-+ return true;
-+
-+ return false;
-+}
-+
-+static uint32_t align_to_chunks_number_per_line(
-+ struct dce112_compressor *cp110,
-+ uint32_t pixels)
-+{
-+ return 256 * ((pixels + 255) / 256);
-+}
-+
-+static void wait_for_fbc_state_changed(
-+ struct dce112_compressor *cp110,
-+ bool enabled)
-+{
-+ uint8_t counter = 0;
-+ uint32_t addr = mmFBC_STATUS;
-+ uint32_t value;
-+
-+ while (counter < 10) {
-+ value = dm_read_reg(cp110->base.ctx, addr);
-+ if (get_reg_field_value(
-+ value,
-+ FBC_STATUS,
-+ FBC_ENABLE_STATUS) == enabled)
-+ break;
-+ udelay(10);
-+ counter++;
-+ }
-+
-+ if (counter == 10) {
-+ dal_logger_write(
-+ cp110->base.ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: wait counter exceeded, changes to HW not applied",
-+ __func__);
-+ }
-+}
-+
-+void dce112_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);
-+ if (compressor->options.bits.CLK_GATING_DISABLED == 1) {
-+ /* HW needs to do power measurement comparison. */
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ FBC_CNTL,
-+ FBC_COMP_CLK_GATE_EN);
-+ }
-+ 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 dce112_compressor_enable_fbc(
-+ struct compressor *compressor,
-+ uint32_t paths_num,
-+ struct compr_addr_and_pitch_params *params)
-+{
-+ struct dce112_compressor *cp110 = TO_DCE112_COMPRESSOR(compressor);
-+
-+ if (compressor->options.bits.FBC_SUPPORT &&
-+ (compressor->options.bits.DUMMY_BACKEND == 0) &&
-+ (!dce112_compressor_is_fbc_enabled_in_hw(compressor, NULL)) &&
-+ (!is_source_bigger_than_epanel_size(
-+ cp110,
-+ params->source_view_width,
-+ params->source_view_height))) {
-+
-+ uint32_t addr;
-+ uint32_t value;
-+
-+ /* Before enabling FBC first need to enable LPT if applicable
-+ * LPT state should always be changed (enable/disable) while FBC
-+ * is disabled */
-+ if (compressor->options.bits.LPT_SUPPORT && (paths_num < 2) &&
-+ (params->source_view_width *
-+ params->source_view_height <=
-+ dce11_one_lpt_channel_max_resolution)) {
-+ dce112_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;
-+ cp110->offsets = reg_offsets[params->inst - 1];
-+
-+ /*Toggle it as there is bug in HW */
-+ set_reg_field_value(value, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
-+ 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(cp110, true);
-+ }
-+}
-+
-+void dce112_compressor_disable_fbc(struct compressor *compressor)
-+{
-+ struct dce112_compressor *cp110 = TO_DCE112_COMPRESSOR(compressor);
-+
-+ if (compressor->options.bits.FBC_SUPPORT &&
-+ dce112_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)
-+ dce112_compressor_disable_lpt(compressor);
-+
-+ wait_for_fbc_state_changed(cp110, false);
-+ }
-+}
-+
-+bool dce112_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_MISC);
-+ if (get_reg_field_value(value, FBC_MISC, FBC_STOP_ON_HFLIP_EVENT)) {
-+ 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 dce112_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 dce112_compressor_program_compressed_surface_address_and_pitch(
-+ struct compressor *compressor,
-+ struct compr_addr_and_pitch_params *params)
-+{
-+ struct dce112_compressor *cp110 = TO_DCE112_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(cp110);
-+
-+ if (lpt_alignment != 0) {
-+ compressed_surf_address_low_part =
-+ ((compressed_surf_address_low_part
-+ + (lpt_alignment - 1)) / lpt_alignment)
-+ * lpt_alignment;
-+ }
-+ }
-+
-+ /* Write address, HIGH has to be first. */
-+ 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(
-+ cp110,
-+ params->source_view_width);
-+
-+ if (compressor->min_compress_ratio == FBC_COMPRESS_RATIO_1TO1)
-+ fbc_pitch = fbc_pitch / 8;
-+ else
-+ dal_logger_write(
-+ compressor->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_CONTROLLER,
-+ "%s: Unexpected DCE11 compression ratio",
-+ __func__);
-+
-+ /* Clear content first. */
-+ 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 dce112_compressor_disable_lpt(struct compressor *compressor)
-+{
-+ struct dce112_compressor *cp110 = TO_DCE112_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 Underlay pipe LPT Stutter */
-+ addr = mmDPGV0_PIPE_STUTTER_CONTROL_NONLPTCH;
-+ value = dm_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DPGV0_PIPE_STUTTER_CONTROL_NONLPTCH,
-+ STUTTER_ENABLE_NONLPTCH);
-+ dm_write_reg(compressor->ctx, addr, 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 dce112_compressor_enable_lpt(struct compressor *compressor)
-+{
-+ struct dce112_compressor *cp110 = TO_DCE112_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);
-+
-+ /* Enable Underlay pipe LPT Stutter */
-+ addr = mmDPGV0_PIPE_STUTTER_CONTROL_NONLPTCH;
-+ value = dm_read_reg(compressor->ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPGV0_PIPE_STUTTER_CONTROL_NONLPTCH,
-+ STUTTER_ENABLE_NONLPTCH);
-+ dm_write_reg(compressor->ctx, addr, value);
-+
-+ /* Selection of Channel(s) containing Compressed Surface: 0xfffffff
-+ * will disable LPT.
-+ * STCTRL_LPT_TARGETn corresponds to channel n. */
-+ addr = mmLOW_POWER_TILING_CONTROL;
-+ value_control = 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 dce112_compressor_program_lpt_control(
-+ struct compressor *compressor,
-+ struct compr_addr_and_pitch_params *params)
-+{
-+ struct dce112_compressor *cp110 = TO_DCE112_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(cp110, lpt_control);
-+
-+ /* Program LOW_POWER_TILING_ROWS_PER_CHAN field which depends on
-+ * FBC compressed surface pitch.
-+ * LOW_POWER_TILING_ROWS_PER_CHAN = Roundup ((Surface Height *
-+ * Surface Pitch) / (Row Size * Number of Channels *
-+ * Number of Banks)). */
-+ rows_per_channel = 0;
-+ lpt_alignment = lpt_size_alignment(cp110);
-+ source_view_width =
-+ align_to_chunks_number_per_line(
-+ cp110,
-+ params->source_view_width);
-+ source_view_height = (params->source_view_height + 1) & (~0x1);
-+
-+ if (lpt_alignment != 0) {
-+ rows_per_channel = source_view_width * source_view_height * 4;
-+ rows_per_channel =
-+ (rows_per_channel % lpt_alignment) ?
-+ (rows_per_channel / lpt_alignment + 1) :
-+ rows_per_channel / lpt_alignment;
-+ }
-+
-+ set_reg_field_value(
-+ lpt_control,
-+ rows_per_channel,
-+ LOW_POWER_TILING_CONTROL,
-+ LOW_POWER_TILING_ROWS_PER_CHAN);
-+
-+ dm_write_reg(compressor->ctx,
-+ mmLOW_POWER_TILING_CONTROL, lpt_control);
-+}
-+
-+/*
-+ * DCE 11 Frame Buffer Compression Implementation
-+ */
-+
-+void dce112_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 DCE11:
-+ * - bit 0 - display register updated
-+ * - bit 28 - memory write from any client except from MCIF
-+ * - bit 29 - CG static screen signal is inactive
-+ * In addition, DCE11.1 also needs to set new DCE11.1 specific events
-+ * that are used to trigger invalidation on certain register changes,
-+ * for example enabling of Alpha Compression may trigger invalidation of
-+ * FBC once bit is set. These events are as follows:
-+ * - Bit 2 - FBC_GRPH_COMP_EN register updated
-+ * - Bit 3 - FBC_SRC_SEL register updated
-+ * - Bit 4 - FBC_MIN_COMPRESSION register updated
-+ * - Bit 5 - FBC_ALPHA_COMP_EN register updated
-+ * - Bit 6 - FBC_ZERO_ALPHA_CHUNK_SKIP_EN register updated
-+ * - Bit 7 - FBC_FORCE_COPY_TO_COMP_BUF register updated
-+ */
-+ addr = mmFBC_IDLE_FORCE_CLEAR_MASK;
-+ value = 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 dce112_compressor_construct(struct dce112_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 *dce112_compressor_create(struct dc_context *ctx,
-+ struct adapter_service *as)
-+{
-+ struct dce112_compressor *cp110 =
-+ dm_alloc(sizeof(struct dce112_compressor));
-+
-+ if (!cp110)
-+ return NULL;
-+
-+ if (dce112_compressor_construct(cp110, ctx, as))
-+ return &cp110->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(cp110);
-+ return NULL;
-+}
-+
-+void dce112_compressor_destroy(struct compressor **compressor)
-+{
-+ dm_free(TO_DCE112_COMPRESSOR(*compressor));
-+ *compressor = NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_compressor.h b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_compressor.h
-new file mode 100644
-index 0000000..bcf4480
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_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_DCE112_H__
-+#define __DC_COMPRESSOR_DCE112_H__
-+
-+#include "../inc/compressor.h"
-+
-+#define TO_DCE112_COMPRESSOR(compressor)\
-+ container_of(compressor, struct dce112_compressor, base)
-+
-+struct dce112_compressor_reg_offsets {
-+ uint32_t dcp_offset;
-+ uint32_t dmif_offset;
-+};
-+
-+struct dce112_compressor {
-+ struct compressor base;
-+ struct dce112_compressor_reg_offsets offsets;
-+};
-+
-+struct compressor *dce112_compressor_create(struct dc_context *ctx,
-+ struct adapter_service *as);
-+
-+bool dce112_compressor_construct(struct dce112_compressor *cp110,
-+ struct dc_context *ctx, struct adapter_service *as);
-+
-+void dce112_compressor_destroy(struct compressor **cp);
-+
-+/* FBC RELATED */
-+void dce112_compressor_power_up_fbc(struct compressor *cp);
-+
-+void dce112_compressor_enable_fbc(struct compressor *cp, uint32_t paths_num,
-+ struct compr_addr_and_pitch_params *params);
-+
-+void dce112_compressor_disable_fbc(struct compressor *cp);
-+
-+void dce112_compressor_set_fbc_invalidation_triggers(struct compressor *cp,
-+ uint32_t fbc_trigger);
-+
-+void dce112_compressor_program_compressed_surface_address_and_pitch(
-+ struct compressor *cp,
-+ struct compr_addr_and_pitch_params *params);
-+
-+bool dce112_compressor_get_required_compressed_surface_size(
-+ struct compressor *cp,
-+ struct fbc_input_info *input_info,
-+ struct fbc_requested_compressed_size *size);
-+
-+bool dce112_compressor_is_fbc_enabled_in_hw(struct compressor *cp,
-+ uint32_t *fbc_mapped_crtc_id);
-+
-+/* LPT RELATED */
-+void dce112_compressor_enable_lpt(struct compressor *cp);
-+
-+void dce112_compressor_disable_lpt(struct compressor *cp);
-+
-+void dce112_compressor_program_lpt_control(struct compressor *cp,
-+ struct compr_addr_and_pitch_params *params);
-+
-+bool dce112_compressor_is_lpt_enabled_in_hw(struct compressor *cp);
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_hw_sequencer.c b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_hw_sequencer.c
-new file mode 100644
-index 0000000..b94130f
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_hw_sequencer.c
-@@ -0,0 +1,178 @@
-+/*
-+ * 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 "dce112_hw_sequencer.h"
-+
-+#include "dce110/dce110_hw_sequencer.h"
-+#include "gpu/dce112/dc_clock_gating_dce112.h"
-+
-+/* include DCE11.2 register header files */
-+#include "dce/dce_11_2_d.h"
-+#include "dce/dce_11_2_sh_mask.h"
-+
-+static void dce112_crtc_switch_to_clk_src(
-+ struct clock_source *clk_src, uint8_t crtc_inst)
-+{
-+ uint32_t pixel_rate_cntl_value;
-+ uint32_t addr;
-+
-+ addr = mmCRTC0_PIXEL_RATE_CNTL + crtc_inst *
-+ (mmCRTC1_PIXEL_RATE_CNTL - mmCRTC0_PIXEL_RATE_CNTL);
-+
-+ pixel_rate_cntl_value = dm_read_reg(clk_src->ctx, addr);
-+
-+ if (clk_src->id == CLOCK_SOURCE_ID_DP_DTO)
-+ set_reg_field_value(pixel_rate_cntl_value, 1,
-+ CRTC0_PIXEL_RATE_CNTL, DP_DTO0_ENABLE);
-+ else {
-+ set_reg_field_value(pixel_rate_cntl_value,
-+ 0,
-+ CRTC0_PIXEL_RATE_CNTL,
-+ DP_DTO0_ENABLE);
-+
-+ set_reg_field_value(pixel_rate_cntl_value,
-+ clk_src->id - 1,
-+ CRTC0_PIXEL_RATE_CNTL,
-+ CRTC0_PIXEL_RATE_SOURCE);
-+ }
-+ dm_write_reg(clk_src->ctx, addr, pixel_rate_cntl_value);
-+}
-+
-+static void dce112_init_pte(struct dc_context *ctx)
-+{
-+ uint32_t addr;
-+ uint32_t value = 0;
-+ uint32_t chunk_int = 0;
-+ uint32_t chunk_mul = 0;
-+
-+ addr = mmUNP_DVMM_PTE_CONTROL;
-+ value = dm_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DVMM_PTE_CONTROL,
-+ DVMM_USE_SINGLE_PTE);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DVMM_PTE_CONTROL,
-+ DVMM_PTE_BUFFER_MODE0);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DVMM_PTE_CONTROL,
-+ DVMM_PTE_BUFFER_MODE1);
-+
-+ dm_write_reg(ctx, addr, value);
-+
-+ addr = mmDVMM_PTE_REQ;
-+ value = dm_read_reg(ctx, addr);
-+
-+ chunk_int = get_reg_field_value(
-+ value,
-+ DVMM_PTE_REQ,
-+ HFLIP_PTEREQ_PER_CHUNK_INT);
-+
-+ chunk_mul = get_reg_field_value(
-+ value,
-+ DVMM_PTE_REQ,
-+ HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
-+
-+ if (chunk_int != 0x4 || chunk_mul != 0x4) {
-+
-+ set_reg_field_value(
-+ value,
-+ 255,
-+ DVMM_PTE_REQ,
-+ MAX_PTEREQ_TO_ISSUE);
-+
-+ set_reg_field_value(
-+ value,
-+ 4,
-+ DVMM_PTE_REQ,
-+ HFLIP_PTEREQ_PER_CHUNK_INT);
-+
-+ set_reg_field_value(
-+ value,
-+ 4,
-+ DVMM_PTE_REQ,
-+ HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
-+
-+ dm_write_reg(ctx, addr, value);
-+ }
-+}
-+
-+static bool dce112_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 (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
-+ return true;
-+
-+ 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 (power_gating != PIPE_GATING_CONTROL_ENABLE)
-+ dce112_init_pte(ctx);
-+
-+ if (bp_result == BP_RESULT_OK)
-+ return true;
-+ else
-+ return false;
-+}
-+
-+bool dce112_hw_sequencer_construct(struct core_dc *dc)
-+{
-+ /* All registers used by dce11.2 match those in dce11 in offset and
-+ * structure
-+ */
-+ dce110_hw_sequencer_construct(dc);
-+ dc->hwss.crtc_switch_to_clk_src = dce112_crtc_switch_to_clk_src;
-+ dc->hwss.enable_display_power_gating = dce112_enable_display_power_gating;
-+ dc->hwss.clock_gating_power_up = dal_dc_clock_gating_dce112_power_up;
-+
-+ return true;
-+}
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_hw_sequencer.h b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_hw_sequencer.h
-new file mode 100644
-index 0000000..d96c582
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_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_DCE112_H__
-+#define __DC_HWSS_DCE112_H__
-+
-+#include "core_types.h"
-+
-+struct core_dc;
-+
-+bool dce112_hw_sequencer_construct(struct core_dc *dc);
-+
-+#endif /* __DC_HWSS_DCE112_H__ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_link_encoder.c b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_link_encoder.c
-new file mode 100644
-index 0000000..23e127c
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_link_encoder.c
-@@ -0,0 +1,116 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dm_services.h"
-+#include "core_types.h"
-+#include "link_encoder.h"
-+#include "stream_encoder.h"
-+#include "dce112_link_encoder.h"
-+#include "../dce110/dce110_link_encoder.h"
-+#include "i2caux_interface.h"
-+#include "dce/dce_11_2_sh_mask.h"
-+
-+/* For current ASICs pixel clock - 600MHz */
-+#define MAX_ENCODER_CLK 600000
-+
-+#define DCE11_UNIPHY_MAX_PIXEL_CLK_IN_KHZ 600000
-+
-+#define DEFAULT_AUX_MAX_DATA_SIZE 16
-+#define AUX_MAX_DEFER_WRITE_RETRY 20
-+
-+/* all values are in milliseconds */
-+/* For eDP, after power-up/power/down,
-+ * 300/500 msec max. delay from LCDVCC to black video generation */
-+#define PANEL_POWER_UP_TIMEOUT 300
-+#define PANEL_POWER_DOWN_TIMEOUT 500
-+#define HPD_CHECK_INTERVAL 10
-+
-+/* Minimum pixel clock, in KHz. For TMDS signal is 25.00 MHz */
-+#define TMDS_MIN_PIXEL_CLOCK 25000
-+/* Maximum pixel clock, in KHz. For TMDS signal is 165.00 MHz */
-+#define TMDS_MAX_PIXEL_CLOCK 165000
-+/* For current ASICs pixel clock - 600MHz */
-+#define MAX_ENCODER_CLOCK 600000
-+
-+enum {
-+ DP_MST_UPDATE_MAX_RETRY = 50
-+};
-+
-+static void dce112_link_encoder_dp_set_phy_pattern(
-+ struct link_encoder *enc,
-+ const struct encoder_set_dp_phy_pattern_param *param)
-+{
-+ switch (param->dp_phy_pattern) {
-+ case DP_TEST_PATTERN_TRAINING_PATTERN4:
-+ dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 3);
-+ break;
-+ default:
-+ dce110_link_encoder_dp_set_phy_pattern(enc, param);
-+ break;
-+ }
-+}
-+
-+static struct link_encoder_funcs dce112_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 = dce110_link_encoder_enable_tmds_output,
-+ .enable_dp_output = dce110_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 = dce112_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,
-+ .destroy = dce110_link_encoder_destroy
-+};
-+
-+bool dce112_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)
-+{
-+ dce110_link_encoder_construct(
-+ enc110,
-+ init_data,
-+ link_regs,
-+ aux_regs,
-+ bl_regs);
-+
-+ enc110->base.funcs = &dce112_lnk_enc_funcs;
-+
-+ enc110->base.features.flags.bits.IS_HBR3_CAPABLE = true;
-+
-+ enc110->base.features.flags.bits.IS_TPS4_CAPABLE = true;
-+
-+ return true;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_link_encoder.h b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_link_encoder.h
-new file mode 100644
-index 0000000..cfc9cc5
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_link_encoder.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_LINK_ENCODER__DCE112_H__
-+#define __DC_LINK_ENCODER__DCE112_H__
-+
-+#include "link_encoder.h"
-+#include "../dce110/dce110_link_encoder.h"
-+
-+bool dce112_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);
-+
-+/****************** HW programming ************************/
-+
-+#endif /* __DC_LINK_ENCODER__DCE112_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c
-new file mode 100644
-index 0000000..823849e
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.c
-@@ -0,0 +1,455 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 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 "dce112_mem_input.h"
-+
-+
-+#include "dce/dce_11_2_d.h"
-+#include "dce/dce_11_2_sh_mask.h"
-+
-+
-+#define DCP_REG(reg) (reg + mem_input110->offsets.dcp)
-+#define DMIF_REG(reg) (reg + mem_input110->offsets.dmif)
-+#define PIPE_REG(reg) (reg + mem_input110->offsets.pipe)
-+
-+static void program_urgency_watermark(
-+ const struct dc_context *ctx,
-+ const uint32_t offset,
-+ struct bw_watermarks marks_low,
-+ uint32_t total_dest_line_time_ns)
-+{
-+ /* register value */
-+ uint32_t urgency_cntl = 0;
-+ uint32_t wm_mask_cntl = 0;
-+
-+ uint32_t urgency_addr = offset + mmDPG_PIPE_URGENCY_CONTROL;
-+ uint32_t wm_addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-+
-+ /*Write mask to enable reading/writing of watermark set A*/
-+ wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-+ set_reg_field_value(wm_mask_cntl,
-+ 0,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ URGENCY_WATERMARK_MASK);
-+ dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-+
-+ urgency_cntl = dm_read_reg(ctx, urgency_addr);
-+
-+ set_reg_field_value(
-+ urgency_cntl,
-+ marks_low.a_mark,
-+ DPG_PIPE_URGENCY_CONTROL,
-+ URGENCY_LOW_WATERMARK);
-+
-+ set_reg_field_value(
-+ urgency_cntl,
-+ total_dest_line_time_ns,
-+ DPG_PIPE_URGENCY_CONTROL,
-+ URGENCY_HIGH_WATERMARK);
-+ dm_write_reg(ctx, urgency_addr, urgency_cntl);
-+
-+ /*Write mask to enable reading/writing of watermark set B*/
-+ wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-+ set_reg_field_value(wm_mask_cntl,
-+ 1,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ URGENCY_WATERMARK_MASK);
-+ dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-+
-+ urgency_cntl = dm_read_reg(ctx, urgency_addr);
-+
-+ set_reg_field_value(urgency_cntl,
-+ marks_low.b_mark,
-+ DPG_PIPE_URGENCY_CONTROL,
-+ URGENCY_LOW_WATERMARK);
-+
-+ set_reg_field_value(urgency_cntl,
-+ total_dest_line_time_ns,
-+ DPG_PIPE_URGENCY_CONTROL,
-+ URGENCY_HIGH_WATERMARK);
-+ dm_write_reg(ctx, urgency_addr, urgency_cntl);
-+
-+ /*Write mask to enable reading/writing of watermark set C*/
-+ wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-+ set_reg_field_value(wm_mask_cntl,
-+ 2,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ URGENCY_WATERMARK_MASK);
-+ dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-+
-+ urgency_cntl = dm_read_reg(ctx, urgency_addr);
-+
-+ set_reg_field_value(urgency_cntl,
-+ marks_low.c_mark,
-+ DPG_PIPE_URGENCY_CONTROL,
-+ URGENCY_LOW_WATERMARK);
-+
-+ set_reg_field_value(urgency_cntl,
-+ total_dest_line_time_ns,
-+ DPG_PIPE_URGENCY_CONTROL,
-+ URGENCY_HIGH_WATERMARK);
-+ dm_write_reg(ctx, urgency_addr, urgency_cntl);
-+
-+ /*Write mask to enable reading/writing of watermark set D*/
-+ wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-+ set_reg_field_value(wm_mask_cntl,
-+ 3,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ URGENCY_WATERMARK_MASK);
-+ dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-+
-+ urgency_cntl = dm_read_reg(ctx, urgency_addr);
-+
-+ set_reg_field_value(urgency_cntl,
-+ marks_low.d_mark,
-+ DPG_PIPE_URGENCY_CONTROL,
-+ URGENCY_LOW_WATERMARK);
-+
-+ set_reg_field_value(urgency_cntl,
-+ total_dest_line_time_ns,
-+ DPG_PIPE_URGENCY_CONTROL,
-+ URGENCY_HIGH_WATERMARK);
-+ dm_write_reg(ctx, urgency_addr, urgency_cntl);
-+}
-+
-+static void program_stutter_watermark(
-+ const struct dc_context *ctx,
-+ const uint32_t offset,
-+ struct bw_watermarks marks)
-+{
-+ /* register value */
-+ uint32_t stutter_cntl = 0;
-+ uint32_t wm_mask_cntl = 0;
-+
-+ uint32_t stutter_addr = offset + mmDPG_PIPE_STUTTER_CONTROL;
-+ uint32_t wm_addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-+
-+ /*Write mask to enable reading/writing of watermark set A*/
-+
-+ wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-+ set_reg_field_value(wm_mask_cntl,
-+ 0,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
-+ dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-+
-+ stutter_cntl = dm_read_reg(ctx, stutter_addr);
-+
-+ set_reg_field_value(stutter_cntl,
-+ 1,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_ENABLE);
-+ set_reg_field_value(stutter_cntl,
-+ 1,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_IGNORE_FBC);
-+
-+ /*Write watermark set A*/
-+ set_reg_field_value(stutter_cntl,
-+ marks.a_mark,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_EXIT_SELF_REFRESH_WATERMARK);
-+ dm_write_reg(ctx, stutter_addr, stutter_cntl);
-+
-+ /*Write mask to enable reading/writing of watermark set B*/
-+ wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-+ set_reg_field_value(wm_mask_cntl,
-+ 1,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
-+ dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-+
-+ stutter_cntl = dm_read_reg(ctx, stutter_addr);
-+ set_reg_field_value(stutter_cntl,
-+ 1,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_ENABLE);
-+ set_reg_field_value(stutter_cntl,
-+ 1,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_IGNORE_FBC);
-+
-+ /*Write watermark set B*/
-+ set_reg_field_value(stutter_cntl,
-+ marks.b_mark,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_EXIT_SELF_REFRESH_WATERMARK);
-+ dm_write_reg(ctx, stutter_addr, stutter_cntl);
-+
-+ /*Write mask to enable reading/writing of watermark set C*/
-+ wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-+ set_reg_field_value(wm_mask_cntl,
-+ 2,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
-+ dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-+
-+ stutter_cntl = dm_read_reg(ctx, stutter_addr);
-+ set_reg_field_value(stutter_cntl,
-+ 1,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_ENABLE);
-+ set_reg_field_value(stutter_cntl,
-+ 1,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_IGNORE_FBC);
-+
-+ /*Write watermark set C*/
-+ set_reg_field_value(stutter_cntl,
-+ marks.c_mark,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_EXIT_SELF_REFRESH_WATERMARK);
-+ dm_write_reg(ctx, stutter_addr, stutter_cntl);
-+
-+ /*Write mask to enable reading/writing of watermark set D*/
-+ wm_mask_cntl = dm_read_reg(ctx, wm_addr);
-+ set_reg_field_value(wm_mask_cntl,
-+ 3,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK);
-+ dm_write_reg(ctx, wm_addr, wm_mask_cntl);
-+
-+ stutter_cntl = dm_read_reg(ctx, stutter_addr);
-+ set_reg_field_value(stutter_cntl,
-+ 1,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_ENABLE);
-+ set_reg_field_value(stutter_cntl,
-+ 1,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_IGNORE_FBC);
-+
-+ /*Write watermark set D*/
-+ set_reg_field_value(stutter_cntl,
-+ marks.d_mark,
-+ DPG_PIPE_STUTTER_CONTROL,
-+ STUTTER_EXIT_SELF_REFRESH_WATERMARK);
-+ dm_write_reg(ctx, stutter_addr, stutter_cntl);
-+}
-+
-+static void program_nbp_watermark(
-+ const struct dc_context *ctx,
-+ const uint32_t offset,
-+ struct bw_watermarks marks)
-+{
-+ uint32_t value;
-+ uint32_t addr;
-+ /* Write mask to enable reading/writing of watermark set A */
-+ addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 0,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ NB_PSTATE_CHANGE_WATERMARK_MASK);
-+ dm_write_reg(ctx, addr, value);
-+
-+ addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_ENABLE);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* Write watermark set A */
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ marks.a_mark,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_WATERMARK);
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* Write mask to enable reading/writing of watermark set B */
-+ addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ NB_PSTATE_CHANGE_WATERMARK_MASK);
-+ dm_write_reg(ctx, addr, value);
-+
-+ addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_ENABLE);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* Write watermark set B */
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ marks.b_mark,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_WATERMARK);
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* Write mask to enable reading/writing of watermark set C */
-+ addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 2,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ NB_PSTATE_CHANGE_WATERMARK_MASK);
-+ dm_write_reg(ctx, addr, value);
-+
-+ addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_ENABLE);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* Write watermark set C */
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ marks.c_mark,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_WATERMARK);
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* Write mask to enable reading/writing of watermark set D */
-+ addr = offset + mmDPG_WATERMARK_MASK_CONTROL;
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 3,
-+ DPG_WATERMARK_MASK_CONTROL,
-+ NB_PSTATE_CHANGE_WATERMARK_MASK);
-+ dm_write_reg(ctx, addr, value);
-+
-+ addr = offset + mmDPG_PIPE_NB_PSTATE_CHANGE_CONTROL;
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_ENABLE);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_URGENT_DURING_REQUEST);
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST);
-+ dm_write_reg(ctx, addr, value);
-+
-+ /* Write watermark set D */
-+ value = dm_read_reg(ctx, addr);
-+ set_reg_field_value(
-+ value,
-+ marks.d_mark,
-+ DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
-+ NB_PSTATE_CHANGE_WATERMARK);
-+ dm_write_reg(ctx, addr, value);
-+}
-+
-+static void dce112_mem_input_program_display_marks(
-+ struct mem_input *mem_input,
-+ struct bw_watermarks nbp,
-+ struct bw_watermarks stutter,
-+ struct bw_watermarks urgent,
-+ uint32_t total_dest_line_time_ns)
-+{
-+ struct dce110_mem_input *bm_dce110 = TO_DCE110_MEM_INPUT(mem_input);
-+
-+ program_urgency_watermark(
-+ mem_input->ctx,
-+ bm_dce110->offsets.dmif,
-+ urgent,
-+ total_dest_line_time_ns);
-+
-+ program_nbp_watermark(
-+ mem_input->ctx,
-+ bm_dce110->offsets.dmif,
-+ nbp);
-+
-+ program_stutter_watermark(
-+ mem_input->ctx,
-+ bm_dce110->offsets.dmif,
-+ stutter);
-+}
-+
-+/*****************************************/
-+/* Constructor, Destructor */
-+/*****************************************/
-+
-+bool dce112_mem_input_construct(
-+ struct dce110_mem_input *mem_input110,
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_mem_input_reg_offsets *offsets)
-+{
-+ if (!dce110_mem_input_construct(mem_input110, ctx, inst, offsets))
-+ return false;
-+
-+ mem_input110->base.funcs->mem_input_program_display_marks =
-+ dce112_mem_input_program_display_marks;
-+
-+ return true;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.h b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.h
-new file mode 100644
-index 0000000..de2aaf0
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_mem_input.h
-@@ -0,0 +1,38 @@
-+/* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DC_MEM_INPUT_DCE112_H__
-+#define __DC_MEM_INPUT_DCE112_H__
-+
-+#include "mem_input.h"
-+#include "dce110/dce110_mem_input.h"
-+
-+bool dce112_mem_input_construct(
-+ struct dce110_mem_input *mem_input110,
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_mem_input_reg_offsets *offsets);
-+
-+
-+#endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.c
-new file mode 100644
-index 0000000..420b8ca
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.c
-@@ -0,0 +1,1404 @@
-+/*
-+* Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 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_resource.h"
-+#include "dce110/dce110_timing_generator.h"
-+#include "dce112/dce112_mem_input.h"
-+#include "dce112/dce112_link_encoder.h"
-+#include "dce110/dce110_link_encoder.h"
-+#include "dce110/dce110_transform.h"
-+#include "dce110/dce110_stream_encoder.h"
-+#include "dce110/dce110_opp.h"
-+#include "dce110/dce110_ipp.h"
-+#include "dce112/dce112_clock_source.h"
-+
-+#include "dce/dce_11_2_d.h"
-+
-+#ifndef mmDP_DPHY_INTERNAL_CTRL
-+ #define mmDP_DPHY_INTERNAL_CTRL 0x4aa7
-+ #define mmDP0_DP_DPHY_INTERNAL_CTRL 0x4aa7
-+ #define mmDP1_DP_DPHY_INTERNAL_CTRL 0x4ba7
-+ #define mmDP2_DP_DPHY_INTERNAL_CTRL 0x4ca7
-+ #define mmDP3_DP_DPHY_INTERNAL_CTRL 0x4da7
-+ #define mmDP4_DP_DPHY_INTERNAL_CTRL 0x4ea7
-+ #define mmDP5_DP_DPHY_INTERNAL_CTRL 0x4fa7
-+ #define mmDP6_DP_DPHY_INTERNAL_CTRL 0x54a7
-+ #define mmDP7_DP_DPHY_INTERNAL_CTRL 0x56a7
-+ #define mmDP8_DP_DPHY_INTERNAL_CTRL 0x57a7
-+#endif
-+
-+enum dce112_clk_src_array_id {
-+ DCE112_CLK_SRC_PLL0,
-+ DCE112_CLK_SRC_PLL1,
-+ DCE112_CLK_SRC_PLL2,
-+ DCE112_CLK_SRC_PLL3,
-+ DCE112_CLK_SRC_PLL4,
-+ DCE112_CLK_SRC_PLL5,
-+
-+ DCE112_CLK_SRC_TOTAL
-+};
-+
-+static const struct dce110_transform_reg_offsets dce112_xfm_offsets[] = {
-+{
-+ .scl_offset = (mmSCL0_SCL_CONTROL - mmSCL_CONTROL),
-+ .dcfe_offset = (mmDCFE0_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .lb_offset = (mmLB0_LB_DATA_FORMAT - mmLB_DATA_FORMAT),
-+},
-+{ .scl_offset = (mmSCL1_SCL_CONTROL - mmSCL_CONTROL),
-+ .dcfe_offset = (mmDCFE1_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .lb_offset = (mmLB1_LB_DATA_FORMAT - mmLB_DATA_FORMAT),
-+},
-+{ .scl_offset = (mmSCL2_SCL_CONTROL - mmSCL_CONTROL),
-+ .dcfe_offset = (mmDCFE2_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .lb_offset = (mmLB2_LB_DATA_FORMAT - mmLB_DATA_FORMAT),
-+},
-+{
-+ .scl_offset = (mmSCL3_SCL_CONTROL - mmSCL_CONTROL),
-+ .dcfe_offset = (mmDCFE3_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .lb_offset = (mmLB3_LB_DATA_FORMAT - mmLB_DATA_FORMAT),
-+},
-+{ .scl_offset = (mmSCL4_SCL_CONTROL - mmSCL_CONTROL),
-+ .dcfe_offset = (mmDCFE4_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .lb_offset = (mmLB4_LB_DATA_FORMAT - mmLB_DATA_FORMAT),
-+},
-+{ .scl_offset = (mmSCL5_SCL_CONTROL - mmSCL_CONTROL),
-+ .dcfe_offset = (mmDCFE5_DCFE_MEM_PWR_CTRL - mmDCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
-+ .lb_offset = (mmLB5_LB_DATA_FORMAT - mmLB_DATA_FORMAT),
-+}
-+};
-+
-+static const struct dce110_timing_generator_offsets dce112_tg_offsets[] = {
-+ {
-+ .crtc = (mmCRTC0_CRTC_CONTROL - mmCRTC_CONTROL),
-+ .dcp = (mmDCP0_GRPH_CONTROL - mmGRPH_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC1_CRTC_CONTROL - mmCRTC_CONTROL),
-+ .dcp = (mmDCP1_GRPH_CONTROL - mmGRPH_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC2_CRTC_CONTROL - mmCRTC_CONTROL),
-+ .dcp = (mmDCP2_GRPH_CONTROL - mmGRPH_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC3_CRTC_CONTROL - mmCRTC_CONTROL),
-+ .dcp = (mmDCP3_GRPH_CONTROL - mmGRPH_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC4_CRTC_CONTROL - mmCRTC_CONTROL),
-+ .dcp = (mmDCP4_GRPH_CONTROL - mmGRPH_CONTROL),
-+ },
-+ {
-+ .crtc = (mmCRTC5_CRTC_CONTROL - mmCRTC_CONTROL),
-+ .dcp = (mmDCP5_GRPH_CONTROL - mmGRPH_CONTROL),
-+ }
-+};
-+
-+static const struct dce110_mem_input_reg_offsets dce112_mi_reg_offsets[] = {
-+ {
-+ .dcp = (mmDCP0_GRPH_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 dce110_ipp_reg_offsets ipp_reg_offsets[] = {
-+{
-+ .dcp_offset = (mmDCP0_CUR_CONTROL - mmCUR_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP1_CUR_CONTROL - mmCUR_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP2_CUR_CONTROL - mmCUR_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP3_CUR_CONTROL - mmCUR_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP4_CUR_CONTROL - mmCUR_CONTROL),
-+},
-+{
-+ .dcp_offset = (mmDCP5_CUR_CONTROL - mmCUR_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_opp_reg_offsets dce112_opp_reg_offsets[] = {
-+{
-+ .fmt_offset = (mmFMT0_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .dcfe_offset = (mmDCFE0_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP0_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{ .fmt_offset = (mmFMT1_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .dcfe_offset = (mmDCFE1_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP1_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{ .fmt_offset = (mmFMT2_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .dcfe_offset = (mmDCFE2_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP2_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{
-+ .fmt_offset = (mmFMT3_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .dcfe_offset = (mmDCFE3_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP3_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{ .fmt_offset = (mmFMT4_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .dcfe_offset = (mmDCFE4_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP4_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+},
-+{ .fmt_offset = (mmFMT5_FMT_CONTROL - mmFMT0_FMT_CONTROL),
-+ .dcfe_offset = (mmDCFE5_DCFE_MEM_PWR_CTRL - mmDCFE0_DCFE_MEM_PWR_CTRL),
-+ .dcp_offset = (mmDCP5_GRPH_CONTROL - mmDCP0_GRPH_CONTROL),
-+}
-+};
-+
-+static const struct dce112_clk_src_reg_offsets dce112_clk_src_reg_offsets[] = {
-+ {
-+ .pixclk_resync_cntl = mmPHYPLLA_PIXCLK_RESYNC_CNTL
-+ },
-+ {
-+ .pixclk_resync_cntl = mmPHYPLLB_PIXCLK_RESYNC_CNTL
-+ },
-+ {
-+ .pixclk_resync_cntl = mmPHYPLLC_PIXCLK_RESYNC_CNTL
-+ },
-+ {
-+ .pixclk_resync_cntl = mmPHYPLLD_PIXCLK_RESYNC_CNTL
-+ },
-+ {
-+ .pixclk_resync_cntl = mmPHYPLLE_PIXCLK_RESYNC_CNTL
-+ },
-+ {
-+ .pixclk_resync_cntl = mmPHYPLLF_PIXCLK_RESYNC_CNTL
-+ }
-+};
-+
-+static struct timing_generator *dce112_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(sizeof(struct dce110_timing_generator));
-+
-+ if (!tg110)
-+ return NULL;
-+
-+ if (dce110_timing_generator_construct(tg110, as, ctx, instance, offsets))
-+ return &tg110->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(tg110);
-+ return NULL;
-+}
-+
-+static struct stream_encoder *dce112_stream_encoder_create(
-+ enum engine_id eng_id,
-+ struct dc_context *ctx,
-+ struct dc_bios *bp,
-+ const struct dce110_stream_enc_registers *regs)
-+{
-+ struct dce110_stream_encoder *enc110 =
-+ dm_alloc(sizeof(struct dce110_stream_encoder));
-+
-+ if (!enc110)
-+ return NULL;
-+
-+ if (dce110_stream_encoder_construct(enc110, ctx, bp, eng_id, regs))
-+ return &enc110->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(enc110);
-+ return NULL;
-+}
-+
-+static struct mem_input *dce112_mem_input_create(
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_mem_input_reg_offsets *offset)
-+{
-+ struct dce110_mem_input *mem_input110 =
-+ dm_alloc(sizeof(struct dce110_mem_input));
-+
-+ if (!mem_input110)
-+ return NULL;
-+
-+ if (dce112_mem_input_construct(mem_input110,
-+ ctx, inst, offset))
-+ return &mem_input110->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(mem_input110);
-+ return NULL;
-+}
-+
-+static void dce112_transform_destroy(struct transform **xfm)
-+{
-+ dm_free(TO_DCE110_TRANSFORM(*xfm));
-+ *xfm = NULL;
-+}
-+
-+static struct transform *dce112_transform_create(
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_transform_reg_offsets *offsets)
-+{
-+ struct dce110_transform *transform =
-+ dm_alloc(sizeof(struct dce110_transform));
-+
-+ if (!transform)
-+ return NULL;
-+
-+ if (dce110_transform_construct(transform, ctx, inst, offsets))
-+ return &transform->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(transform);
-+ return NULL;
-+}
-+struct link_encoder *dce112_link_encoder_create(
-+ const struct encoder_init_data *enc_init_data)
-+{
-+ struct dce110_link_encoder *enc110 =
-+ dm_alloc(sizeof(struct dce110_link_encoder));
-+
-+ if (!enc110)
-+ return NULL;
-+
-+ if (dce112_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(enc110);
-+ return NULL;
-+}
-+
-+struct input_pixel_processor *dce112_ipp_create(
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_ipp_reg_offsets *offset)
-+{
-+ struct dce110_ipp *ipp =
-+ dm_alloc(sizeof(struct dce110_ipp));
-+
-+ if (!ipp)
-+ return NULL;
-+
-+ if (dce110_ipp_construct(ipp, ctx, inst, offset))
-+ return &ipp->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(ipp);
-+ return NULL;
-+}
-+
-+void dce112_ipp_destroy(struct input_pixel_processor **ipp)
-+{
-+ dm_free(TO_DCE110_IPP(*ipp));
-+ *ipp = NULL;
-+}
-+
-+struct output_pixel_processor *dce112_opp_create(
-+ struct dc_context *ctx,
-+ uint32_t inst,
-+ const struct dce110_opp_reg_offsets *offset)
-+{
-+ struct dce110_opp *opp =
-+ dm_alloc(sizeof(struct dce110_opp));
-+
-+ if (!opp)
-+ return NULL;
-+
-+ if (dce110_opp_construct(opp,
-+ ctx, inst, offset))
-+ return &opp->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ dm_free(opp);
-+ return NULL;
-+}
-+
-+void dce112_opp_destroy(struct output_pixel_processor **opp)
-+{
-+ dm_free(FROM_DCE11_OPP(*opp)->regamma.coeff128_dx);
-+ dm_free(FROM_DCE11_OPP(*opp)->regamma.coeff128_oem);
-+ dm_free(FROM_DCE11_OPP(*opp)->regamma.coeff128);
-+ dm_free(FROM_DCE11_OPP(*opp)->regamma.axis_x_1025);
-+ dm_free(FROM_DCE11_OPP(*opp)->regamma.axis_x_256);
-+ dm_free(FROM_DCE11_OPP(*opp)->regamma.coordinates_x);
-+ dm_free(FROM_DCE11_OPP(*opp)->regamma.rgb_regamma);
-+ dm_free(FROM_DCE11_OPP(*opp)->regamma.rgb_resulted);
-+ dm_free(FROM_DCE11_OPP(*opp)->regamma.rgb_oem);
-+ dm_free(FROM_DCE11_OPP(*opp)->regamma.rgb_user);
-+ dm_free(FROM_DCE11_OPP(*opp));
-+ *opp = NULL;
-+}
-+
-+struct clock_source *dce112_clock_source_create(
-+ struct dc_context *ctx,
-+ struct dc_bios *bios,
-+ enum clock_source_id id,
-+ const struct dce112_clk_src_reg_offsets *offsets)
-+{
-+ struct dce112_clk_src *clk_src =
-+ dm_alloc(sizeof(struct dce112_clk_src));
-+
-+ if (!clk_src)
-+ return NULL;
-+
-+ if (dce112_clk_src_construct(clk_src, ctx, bios, id, offsets))
-+ return &clk_src->base;
-+
-+ BREAK_TO_DEBUGGER();
-+ return NULL;
-+}
-+
-+void dce112_clock_source_destroy(struct clock_source **clk_src)
-+{
-+ dm_free(TO_DCE112_CLK_SRC(*clk_src));
-+ *clk_src = NULL;
-+}
-+
-+void dce112_destruct_resource_pool(struct resource_pool *pool)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < pool->pipe_count; i++) {
-+ if (pool->opps[i] != NULL)
-+ dce112_opp_destroy(&pool->opps[i]);
-+
-+ if (pool->transforms[i] != NULL)
-+ dce112_transform_destroy(&pool->transforms[i]);
-+
-+ if (pool->ipps[i] != NULL)
-+ dce112_ipp_destroy(&pool->ipps[i]);
-+
-+ if (pool->mis[i] != NULL) {
-+ dm_free(TO_DCE110_MEM_INPUT(pool->mis[i]));
-+ pool->mis[i] = NULL;
-+ }
-+
-+ if (pool->timing_generators[i] != NULL) {
-+ dm_free(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(DCE110STRENC_FROM_STRENC(pool->stream_enc[i]));
-+ }
-+
-+ for (i = 0; i < pool->clk_src_count; i++) {
-+ if (pool->clock_sources[i] != NULL) {
-+ dce112_clock_source_destroy(&pool->clock_sources[i]);
-+ }
-+ }
-+
-+ if (pool->dp_clock_source != NULL)
-+ dce112_clock_source_destroy(&pool->dp_clock_source);
-+
-+ 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_matching_pll(struct resource_context *res_ctx,
-+ const struct core_stream *const stream)
-+{
-+ switch (stream->sink->link->link_enc->transmitter) {
-+ case TRANSMITTER_UNIPHY_A:
-+ return res_ctx->pool.clock_sources[DCE112_CLK_SRC_PLL0];
-+ case TRANSMITTER_UNIPHY_B:
-+ return res_ctx->pool.clock_sources[DCE112_CLK_SRC_PLL1];
-+ case TRANSMITTER_UNIPHY_C:
-+ return res_ctx->pool.clock_sources[DCE112_CLK_SRC_PLL2];
-+ case TRANSMITTER_UNIPHY_D:
-+ return res_ctx->pool.clock_sources[DCE112_CLK_SRC_PLL3];
-+ case TRANSMITTER_UNIPHY_E:
-+ return res_ctx->pool.clock_sources[DCE112_CLK_SRC_PLL4];
-+ case TRANSMITTER_UNIPHY_F:
-+ return res_ctx->pool.clock_sources[DCE112_CLK_SRC_PLL5];
-+ default:
-+ return NULL;
-+ };
-+
-+ 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 core_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;
-+
-+ resource_build_info_frame(pipe_ctx);
-+
-+ /* do not need to validate non root pipes */
-+ break;
-+ }
-+ }
-+ }
-+
-+ return DC_OK;
-+}
-+
-+enum dc_status dce112_validate_bandwidth(
-+ const struct core_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->scl_data.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->scl_data.ratios.vert.value);
-+ disp->graphics_h_taps = pipe_ctx->scl_data.taps.h_taps;
-+ disp->graphics_v_taps = pipe_ctx->scl_data.taps.v_taps;
-+
-+ /* TODO: remove when bw formula accepts taps per
-+ * display
-+ */
-+ if (max_vtaps < pipe_ctx->scl_data.taps.v_taps)
-+ max_vtaps = pipe_ctx->scl_data.taps.v_taps;
-+ if (max_htaps < pipe_ctx->scl_data.taps.h_taps)
-+ max_htaps = pipe_ctx->scl_data.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 (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 (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 core_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.dp_clock_source;
-+ else
-+ pipe_ctx->clock_source =
-+ find_matching_pll(&context->res_ctx,
-+ stream);
-+
-+ if (pipe_ctx->clock_source == NULL)
-+ return DC_NO_CLOCK_SOURCE_RESOURCE;
-+
-+ 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 dce112_validate_with_context(
-+ const struct core_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);
-+ dc_target_retain(&context->targets[i]->public);
-+ 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);
-+ resource_attach_surfaces_to_context(
-+ (struct dc_surface **)dc->current_context.
-+ target_status[j].surfaces,
-+ dc->current_context.target_status[j].surface_count,
-+ &context->targets[i]->public,
-+ context);
-+ context->target_status[i] =
-+ dc->current_context.target_status[j];
-+ }
-+ if (!unchanged || set[i].surface_count != 0)
-+ if (!resource_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 = resource_map_pool_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)
-+ resource_build_scaling_params_for_context(dc, context);
-+
-+ if (result == DC_OK)
-+ result = dce112_validate_bandwidth(dc, context);
-+
-+ return result;
-+}
-+
-+static struct resource_funcs dce112_res_pool_funcs = {
-+ .destruct = dce112_destruct_resource_pool,
-+ .link_enc_create = dce112_link_encoder_create,
-+ .validate_with_context = dce112_validate_with_context,
-+ .validate_bandwidth = dce112_validate_bandwidth
-+};
-+
-+static void bw_calcs_data_update_from_pplib(struct core_dc *dc)
-+{
-+ struct dm_pp_clock_levels clks = {0};
-+
-+ /*do system clock*/
-+ dm_pp_get_clock_levels_by_type(
-+ dc->ctx,
-+ DM_PP_CLOCK_TYPE_ENGINE_CLK,
-+ &clks);
-+ /* convert all the clock fro kHz to fix point mHz */
-+ dc->bw_vbios.high_sclk = bw_frc_to_fixed(
-+ clks.clocks_in_khz[clks.num_levels-1], 1000);
-+ dc->bw_vbios.mid_sclk = bw_frc_to_fixed(
-+ clks.clocks_in_khz[clks.num_levels>>1], 1000);
-+ dc->bw_vbios.low_sclk = bw_frc_to_fixed(
-+ clks.clocks_in_khz[0], 1000);
-+
-+ /*do display clock*/
-+ dm_pp_get_clock_levels_by_type(
-+ dc->ctx,
-+ DM_PP_CLOCK_TYPE_DISPLAY_CLK,
-+ &clks);
-+
-+ dc->bw_vbios.high_voltage_max_dispclk = bw_frc_to_fixed(
-+ clks.clocks_in_khz[clks.num_levels-1], 1000);
-+ dc->bw_vbios.mid_voltage_max_dispclk = bw_frc_to_fixed(
-+ clks.clocks_in_khz[clks.num_levels>>1], 1000);
-+ dc->bw_vbios.low_voltage_max_dispclk = bw_frc_to_fixed(
-+ clks.clocks_in_khz[0], 1000);
-+
-+ /*do memory clock*/
-+ dm_pp_get_clock_levels_by_type(
-+ dc->ctx,
-+ DM_PP_CLOCK_TYPE_MEMORY_CLK,
-+ &clks);
-+
-+ dc->bw_vbios.low_yclk = bw_frc_to_fixed(
-+ clks.clocks_in_khz[0] * MEMORY_TYPE_MULTIPLIER, 1000);
-+ dc->bw_vbios.mid_yclk = bw_frc_to_fixed(
-+ clks.clocks_in_khz[clks.num_levels>>1] * MEMORY_TYPE_MULTIPLIER,
-+ 1000);
-+ dc->bw_vbios.high_yclk = bw_frc_to_fixed(
-+ clks.clocks_in_khz[clks.num_levels-1] * MEMORY_TYPE_MULTIPLIER,
-+ 1000);
-+}
-+
-+
-+bool dce112_construct_resource_pool(
-+ struct adapter_service *adapter_serv,
-+ uint8_t num_virtual_links,
-+ struct core_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 = &dce112_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[DCE112_CLK_SRC_PLL0] = dce112_clock_source_create(
-+ ctx, dal_adapter_service_get_bios_parser(adapter_serv),
-+ CLOCK_SOURCE_COMBO_PHY_PLL0, &dce112_clk_src_reg_offsets[0]);
-+ pool->clock_sources[DCE112_CLK_SRC_PLL1] = dce112_clock_source_create(
-+ ctx, dal_adapter_service_get_bios_parser(adapter_serv),
-+ CLOCK_SOURCE_COMBO_PHY_PLL1, &dce112_clk_src_reg_offsets[1]);
-+ pool->clock_sources[DCE112_CLK_SRC_PLL2] = dce112_clock_source_create(
-+ ctx, dal_adapter_service_get_bios_parser(adapter_serv),
-+ CLOCK_SOURCE_COMBO_PHY_PLL2, &dce112_clk_src_reg_offsets[2]);
-+ pool->clock_sources[DCE112_CLK_SRC_PLL3] = dce112_clock_source_create(
-+ ctx, dal_adapter_service_get_bios_parser(adapter_serv),
-+ CLOCK_SOURCE_COMBO_PHY_PLL3, &dce112_clk_src_reg_offsets[3]);
-+ pool->clock_sources[DCE112_CLK_SRC_PLL4] = dce112_clock_source_create(
-+ ctx, dal_adapter_service_get_bios_parser(adapter_serv),
-+ CLOCK_SOURCE_COMBO_PHY_PLL4, &dce112_clk_src_reg_offsets[4]);
-+ pool->clock_sources[DCE112_CLK_SRC_PLL5] = dce112_clock_source_create(
-+ ctx, dal_adapter_service_get_bios_parser(adapter_serv),
-+ CLOCK_SOURCE_COMBO_PHY_PLL5, &dce112_clk_src_reg_offsets[5]);
-+ pool->clk_src_count = DCE112_CLK_SRC_TOTAL;
-+
-+ pool->dp_clock_source = dce112_clock_source_create(
-+ ctx, dal_adapter_service_get_bios_parser(adapter_serv),
-+ CLOCK_SOURCE_ID_DP_DTO, &dce112_clk_src_reg_offsets[0]);
-+
-+ 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_dce112_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 = 6;
-+ 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] = dce112_timing_generator_create(
-+ adapter_serv,
-+ ctx,
-+ i,
-+ &dce112_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] = dce112_mem_input_create(
-+ ctx,
-+ i,
-+ &dce112_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] = dce112_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] = dce112_transform_create(
-+ ctx,
-+ i,
-+ &dce112_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] = dce112_opp_create(
-+ ctx,
-+ i,
-+ &dce112_opp_reg_offsets[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++) {
-+ /* TODO: rework fragile code*/
-+ if (pool->stream_engines.u_all & 1 << i) {
-+ pool->stream_enc[i] = dce112_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++;
-+ }
-+
-+ /* Create hardware sequencer */
-+ if (!dc_construct_hw_sequencer(adapter_serv, dc))
-+ goto stream_enc_create_fail;
-+
-+ bw_calcs_init(&dc->bw_dceip, &dc->bw_vbios, BW_CALCS_VERSION_BAFFIN);
-+
-+ bw_calcs_data_update_from_pplib(dc);
-+
-+ return true;
-+
-+stream_enc_create_fail:
-+ for (i = 0; i < pool->stream_enc_count; i++) {
-+ if (pool->stream_enc[i] != NULL)
-+ dm_free(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)
-+ dce112_opp_destroy(&pool->opps[i]);
-+
-+ if (pool->transforms[i] != NULL)
-+ dce112_transform_destroy(&pool->transforms[i]);
-+
-+ if (pool->ipps[i] != NULL)
-+ dce112_ipp_destroy(&pool->ipps[i]);
-+
-+ if (pool->mis[i] != NULL) {
-+ dm_free(TO_DCE110_MEM_INPUT(pool->mis[i]));
-+ pool->mis[i] = NULL;
-+ }
-+
-+ if (pool->timing_generators[i] != NULL) {
-+ dm_free(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)
-+ dce112_clock_source_destroy(&pool->clock_sources[i]);
-+ }
-+
-+ return false;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.h b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_resource.h
-new file mode 100644
-index 0000000..eed1faf
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/dce112/dce112_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_DCE112_H__
-+#define __DC_RESOURCE_DCE112_H__
-+
-+#include "core_types.h"
-+
-+struct adapter_service;
-+struct core_dc;
-+struct resource_pool;
-+
-+bool dce112_construct_resource_pool(
-+ struct adapter_service *adapter_serv,
-+ uint8_t num_virtual_links,
-+ struct core_dc *dc,
-+ struct resource_pool *pool);
-+
-+#endif /* __DC_RESOURCE_DCE112_H__ */
-+
-diff --git a/drivers/gpu/drm/amd/dal/dc/dm_services_types.h b/drivers/gpu/drm/amd/dal/dc/dm_services_types.h
-index 1e87624..982e968 100644
---- a/drivers/gpu/drm/amd/dal/dc/dm_services_types.h
-+++ b/drivers/gpu/drm/amd/dal/dc/dm_services_types.h
-@@ -212,6 +212,11 @@ enum dm_pp_clock_type {
- struct dm_pp_clock_levels {
- uint32_t num_levels;
- uint32_t clocks_in_khz[DM_PP_MAX_CLOCK_LEVELS];
-+
-+ /* TODO: add latency for polaris11
-+ * do we need to know invalid (unsustainable boost) level for watermark
-+ * programming? if not we can just report less elements in array
-+ */
- };
-
- struct dm_pp_single_disp_config {
-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 63d6b54..5037a2d 100644
---- a/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c
-@@ -78,6 +78,9 @@ bool dal_hw_factory_init(
- #endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
- case DCE_VERSION_11_0:
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ case DCE_VERSION_11_2:
-+#endif
- dal_hw_factory_dce110_init(factory);
- return true;
- #endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c
-index d3c6bc8..da56db7 100644
---- a/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c
-+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c
-@@ -75,6 +75,9 @@ bool dal_hw_translate_init(
- case DCE_VERSION_10_0:
- #endif
- case DCE_VERSION_11_0:
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ case DCE_VERSION_11_2:
-+#endif
- dal_hw_translate_dce110_init(translate);
- return true;
- #endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/Makefile b/drivers/gpu/drm/amd/dal/dc/gpu/Makefile
-index cb23508..3095006 100644
---- a/drivers/gpu/drm/amd/dal/dc/gpu/Makefile
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/Makefile
-@@ -32,3 +32,11 @@ AMD_DAL_GPU_DCE110 = $(addprefix $(AMDDALPATH)/dc/gpu/dce110/,$(GPU_DCE110))
-
- AMD_DAL_FILES += $(AMD_DAL_GPU_DCE110)
- endif
-+
-+ifdef CONFIG_DRM_AMD_DAL_DCE11_2
-+GPU_DCE112 = display_clock_dce112.o dc_clock_gating_dce112.o
-+
-+AMD_DAL_GPU_DCE112 = $(addprefix $(AMDDALPATH)/dc/gpu/dce112/,$(GPU_DCE112))
-+
-+AMD_DAL_FILES += $(AMD_DAL_GPU_DCE110) $(AMD_DAL_GPU_DCE112)
-+endif
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce112/dc_clock_gating_dce112.c b/drivers/gpu/drm/amd/dal/dc/gpu/dce112/dc_clock_gating_dce112.c
-new file mode 100644
-index 0000000..bf24457
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce112/dc_clock_gating_dce112.c
-@@ -0,0 +1,89 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#include "dm_services.h"
-+
-+#include "include/logger_interface.h"
-+
-+#include "dce/dce_11_2_d.h"
-+#include "dce/dce_11_2_sh_mask.h"
-+#include "dc_clock_gating_dce112.h"
-+
-+/******************************************************************************
-+ * Macro definitions
-+ *****************************************************************************/
-+
-+#define NOT_IMPLEMENTED() DAL_LOGGER_NOT_IMPL(LOG_MINOR_COMPONENT_GPU, \
-+ "%s:%s()\n", __FILE__, __func__)
-+
-+/******************************************************************************
-+ * static functions
-+ *****************************************************************************/
-+static void force_hw_base_light_sleep(struct dc_context *ctx)
-+{
-+ uint32_t addr = 0;
-+ uint32_t value = 0;
-+
-+ addr = mmDC_MEM_GLOBAL_PWR_REQ_CNTL;
-+ /* Read the mmDC_MEM_GLOBAL_PWR_REQ_CNTL to get the currently
-+ * programmed DC_MEM_GLOBAL_PWR_REQ_DIS*/
-+ value = dm_read_reg(ctx, addr);
-+
-+ set_reg_field_value(
-+ value,
-+ 1,
-+ DC_MEM_GLOBAL_PWR_REQ_CNTL,
-+ DC_MEM_GLOBAL_PWR_REQ_DIS);
-+
-+ dm_write_reg(ctx, addr, value);
-+
-+}
-+
-+static void enable_hw_base_light_sleep(struct dc_context *ctx)
-+{
-+ NOT_IMPLEMENTED();
-+}
-+
-+static void disable_sw_manual_control_light_sleep(
-+ struct dc_context *ctx)
-+{
-+ NOT_IMPLEMENTED();
-+}
-+
-+/******************************************************************************
-+ * public functions
-+ *****************************************************************************/
-+
-+void dal_dc_clock_gating_dce112_power_up(
-+ struct dc_context *ctx,
-+ bool enable)
-+{
-+ if (enable) {
-+ enable_hw_base_light_sleep(ctx);
-+ disable_sw_manual_control_light_sleep(ctx);
-+ } else {
-+ force_hw_base_light_sleep(ctx);
-+ }
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce112/dc_clock_gating_dce112.h b/drivers/gpu/drm/amd/dal/dc/gpu/dce112/dc_clock_gating_dce112.h
-new file mode 100644
-index 0000000..118da64
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce112/dc_clock_gating_dce112.h
-@@ -0,0 +1,33 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+ * OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ * Authors: AMD
-+ *
-+ */
-+
-+#ifndef __DAL_DC_CLOCK_GATING_DCE112_H__
-+#define __DAL_DC_CLOCK_GATING_DCE112_H__
-+
-+void dal_dc_clock_gating_dce112_power_up(
-+ struct dc_context *ctx,
-+ bool enable);
-+
-+#endif /* __DAL_DC_CLOCK_GATING_DCE110_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce112/display_clock_dce112.c b/drivers/gpu/drm/amd/dal/dc/gpu/dce112/display_clock_dce112.c
-new file mode 100644
-index 0000000..e559f95
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce112/display_clock_dce112.c
-@@ -0,0 +1,964 @@
-+/*
-+ * Copyright 2012-15 Advanced Micro Devices, Inc.
-+ *
-+ * Permission is hereby granted, free of charge, to any person obtaining a
-+ * copy of this software and associated documentation files (the "Software"),
-+ * to deal in the Software without restriction, including without limitation
-+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-+ * and/or sell copies of the Software, and to permit persons to whom the
-+ * Software is furnished to do so, subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be included in
-+ * all copies or substantial portions of the Software.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 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_11_2_d.h"
-+#include "dce/dce_11_2_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_dce112.h"
-+
-+#define FROM_DISPLAY_CLOCK(base) \
-+ container_of(base, struct display_clock_dce112, disp_clk_base)
-+
-+static struct state_dependent_clocks max_clks_by_state[] = {
-+/*ClocksStateInvalid - should not be used*/
-+{ .display_clk_khz = 0, .pixel_clk_khz = 0 },
-+/*ClocksStateUltraLow - currently by HW design team not supposed to be used*/
-+{ .display_clk_khz = 352000, .pixel_clk_khz = 330000 },
-+/*ClocksStateLow*/
-+{ .display_clk_khz = 352000, .pixel_clk_khz = 330000 },
-+/*ClocksStateNominal*/
-+{ .display_clk_khz = 467000, .pixel_clk_khz = 400000 },
-+/*ClocksStatePerformance*/
-+{ .display_clk_khz = 643000, .pixel_clk_khz = 4000000 } };
-+
-+/* Starting point for each divider range.*/
-+enum divider_range_start {
-+ DIVIDER_RANGE_01_START = 200, /* 2.00*/
-+ DIVIDER_RANGE_02_START = 1600, /* 16.00*/
-+ DIVIDER_RANGE_03_START = 3200, /* 32.00*/
-+ DIVIDER_RANGE_SCALE_FACTOR = 100 /* Results are scaled up by 100.*/
-+};
-+
-+/* Array identifiers and count for the divider ranges.*/
-+enum divider_range_count {
-+ DIVIDER_RANGE_01 = 0,
-+ DIVIDER_RANGE_02,
-+ DIVIDER_RANGE_03,
-+ DIVIDER_RANGE_MAX /* == 3*/
-+};
-+
-+/* Ranges for divider identifiers (Divider ID or DID)
-+ mmDENTIST_DISPCLK_CNTL.DENTIST_DISPCLK_WDIVIDER*/
-+enum divider_id_register_setting {
-+ DIVIDER_RANGE_01_BASE_DIVIDER_ID = 0X08,
-+ DIVIDER_RANGE_02_BASE_DIVIDER_ID = 0X40,
-+ DIVIDER_RANGE_03_BASE_DIVIDER_ID = 0X60,
-+ DIVIDER_RANGE_MAX_DIVIDER_ID = 0X80
-+};
-+
-+/* Step size between each divider within a range.
-+ Incrementing the DENTIST_DISPCLK_WDIVIDER by one
-+ will increment the divider by this much.*/
-+enum divider_range_step_size {
-+ DIVIDER_RANGE_01_STEP_SIZE = 25, /* 0.25*/
-+ DIVIDER_RANGE_02_STEP_SIZE = 50, /* 0.50*/
-+ DIVIDER_RANGE_03_STEP_SIZE = 100 /* 1.00 */
-+};
-+
-+static struct divider_range divider_ranges[DIVIDER_RANGE_MAX];
-+
-+#define dce112_DFS_BYPASS_THRESHOLD_KHZ 400000
-+/*****************************************************************************
-+ * static functions
-+ *****************************************************************************/
-+
-+/*
-+ * store_max_clocks_state
-+ *
-+ * @brief
-+ * Cache the clock state
-+ *
-+ * @param
-+ * struct display_clock *base - [out] cach the state in this structure
-+ * enum clocks_state max_clocks_state - [in] state to be stored
-+ */
-+static void store_max_clocks_state(
-+ struct display_clock *base,
-+ enum clocks_state max_clocks_state)
-+{
-+ struct display_clock_dce112 *dc = DCLCK112_FROM_BASE(base);
-+
-+ switch (max_clocks_state) {
-+ case CLOCKS_STATE_LOW:
-+ case CLOCKS_STATE_NOMINAL:
-+ case CLOCKS_STATE_PERFORMANCE:
-+ case CLOCKS_STATE_ULTRA_LOW:
-+ dc->max_clks_state = max_clocks_state;
-+ break;
-+
-+ case CLOCKS_STATE_INVALID:
-+ default:
-+ /*Invalid Clocks State!*/
-+ ASSERT_CRITICAL(false);
-+ break;
-+ }
-+}
-+
-+static enum clocks_state get_min_clocks_state(struct display_clock *base)
-+{
-+ return base->cur_min_clks_state;
-+}
-+
-+static bool set_min_clocks_state(
-+ struct display_clock *base,
-+ enum clocks_state clocks_state)
-+{
-+ struct display_clock_dce112 *dc = DCLCK112_FROM_BASE(base);
-+
-+ if (clocks_state > dc->max_clks_state) {
-+ /*Requested state exceeds max supported state.*/
-+ dal_logger_write(base->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Requested state exceeds max supported state");
-+ return false;
-+ } else if (clocks_state == base->cur_min_clks_state) {
-+ /*if we're trying to set the same state, we can just return
-+ * since nothing needs to be done*/
-+ return true;
-+ }
-+
-+ base->cur_min_clks_state = clocks_state;
-+
-+ return true;
-+}
-+
-+static uint32_t get_dp_ref_clk_frequency(struct display_clock *dc)
-+{
-+ uint32_t dispclk_cntl_value;
-+ uint32_t dp_ref_clk_cntl_value;
-+ uint32_t dp_ref_clk_cntl_src_sel_value;
-+ uint32_t dp_ref_clk_khz = 600000;
-+ uint32_t target_div = INVALID_DIVIDER;
-+ struct display_clock_dce112 *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 destroy(struct display_clock **base)
-+{
-+ struct display_clock_dce112 *dc112;
-+
-+ dc112 = DCLCK112_FROM_BASE(*base);
-+
-+ dm_free(dc112);
-+
-+ *base = NULL;
-+}
-+
-+static uint32_t get_validation_clock(struct display_clock *dc)
-+{
-+ uint32_t clk = 0;
-+ struct display_clock_dce112 *disp_clk = DCLCK112_FROM_BASE(dc);
-+
-+ switch (disp_clk->max_clks_state) {
-+ case CLOCKS_STATE_ULTRA_LOW:
-+ /*Currently not supported, it has 0 in table entry*/
-+ case CLOCKS_STATE_LOW:
-+ clk = max_clks_by_state[CLOCKS_STATE_LOW].
-+ display_clk_khz;
-+ break;
-+
-+ case CLOCKS_STATE_NOMINAL:
-+ clk = max_clks_by_state[CLOCKS_STATE_NOMINAL].
-+ display_clk_khz;
-+ break;
-+
-+ case CLOCKS_STATE_PERFORMANCE:
-+ clk = max_clks_by_state[CLOCKS_STATE_PERFORMANCE].
-+ display_clk_khz;
-+ break;
-+
-+ case CLOCKS_STATE_INVALID:
-+ default:
-+ /*Invalid Clocks State*/
-+ dal_logger_write(dc->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Invalid clock state");
-+ /* just return the display engine clock for
-+ * lowest supported state*/
-+ clk = max_clks_by_state[CLOCKS_STATE_LOW].
-+ display_clk_khz;
-+ break;
-+ }
-+ return clk;
-+}
-+
-+static struct fixed32_32 get_deep_color_factor(struct min_clock_params *params)
-+{
-+ /* DeepColorFactor = IF (HDMI = True, bpp / 24, 1)*/
-+ struct fixed32_32 deep_color_factor = dal_fixed32_32_from_int(1);
-+
-+ if (params->signal_type != SIGNAL_TYPE_HDMI_TYPE_A)
-+ return deep_color_factor;
-+
-+ switch (params->deep_color_depth) {
-+ case COLOR_DEPTH_101010:
-+ /*deep color ratio for 30bpp is 30/24 = 1.25*/
-+ deep_color_factor = dal_fixed32_32_from_fraction(30, 24);
-+ break;
-+
-+ case COLOR_DEPTH_121212:
-+ /* deep color ratio for 36bpp is 36/24 = 1.5*/
-+ deep_color_factor = dal_fixed32_32_from_fraction(36, 24);
-+ break;
-+
-+ case COLOR_DEPTH_161616:
-+ /* deep color ratio for 48bpp is 48/24 = 2.0 */
-+ deep_color_factor = dal_fixed32_32_from_fraction(48, 24);
-+ break;
-+ default:
-+ break;
-+ }
-+ return deep_color_factor;
-+}
-+
-+static struct fixed32_32 get_scaler_efficiency(
-+ struct dc_context *ctx,
-+ struct min_clock_params *params)
-+{
-+ struct fixed32_32 scaler_efficiency = dal_fixed32_32_from_int(3);
-+
-+ if (params->scaler_efficiency == V_SCALER_EFFICIENCY_LB18BPP) {
-+ scaler_efficiency =
-+ dal_fixed32_32_add(
-+ dal_fixed32_32_from_fraction(35555, 10000),
-+ dal_fixed32_32_from_fraction(
-+ 55556,
-+ 100000 * 10000));
-+ } else if (params->scaler_efficiency == V_SCALER_EFFICIENCY_LB24BPP) {
-+ scaler_efficiency =
-+ dal_fixed32_32_add(
-+ dal_fixed32_32_from_fraction(34285, 10000),
-+ dal_fixed32_32_from_fraction(
-+ 71429,
-+ 100000 * 10000));
-+ } else if (params->scaler_efficiency == V_SCALER_EFFICIENCY_LB30BPP)
-+ scaler_efficiency = dal_fixed32_32_from_fraction(32, 10);
-+
-+ return scaler_efficiency;
-+}
-+
-+static struct fixed32_32 get_lb_lines_in_per_line_out(
-+ struct min_clock_params *params,
-+ struct fixed32_32 v_scale_ratio)
-+{
-+ struct fixed32_32 two = dal_fixed32_32_from_int(2);
-+ struct fixed32_32 four = dal_fixed32_32_from_int(4);
-+ struct fixed32_32 f4_to_3 = dal_fixed32_32_from_fraction(4, 3);
-+ struct fixed32_32 f6_to_4 = dal_fixed32_32_from_fraction(6, 4);
-+
-+ if (params->line_buffer_prefetch_enabled)
-+ return dal_fixed32_32_max(v_scale_ratio, dal_fixed32_32_one);
-+ else if (dal_fixed32_32_le(v_scale_ratio, dal_fixed32_32_one))
-+ return dal_fixed32_32_one;
-+ else if (dal_fixed32_32_le(v_scale_ratio, f4_to_3))
-+ return f4_to_3;
-+ else if (dal_fixed32_32_le(v_scale_ratio, f6_to_4))
-+ return f6_to_4;
-+ else if (dal_fixed32_32_le(v_scale_ratio, two))
-+ return two;
-+ else if (dal_fixed32_32_le(v_scale_ratio, dal_fixed32_32_from_int(3)))
-+ return four;
-+ else
-+ return dal_fixed32_32_zero;
-+}
-+
-+static uint32_t get_actual_required_display_clk(
-+ struct display_clock_dce112 *disp_clk,
-+ uint32_t target_clk_khz)
-+{
-+ uint32_t disp_clk_khz = target_clk_khz;
-+ uint32_t div = INVALID_DIVIDER;
-+ uint32_t did = INVALID_DID;
-+ uint32_t scaled_vco =
-+ disp_clk->dentist_vco_freq_khz * DIVIDER_RANGE_SCALE_FACTOR;
-+
-+ ASSERT_CRITICAL(!!disp_clk_khz);
-+
-+ if (disp_clk_khz)
-+ div = scaled_vco / disp_clk_khz;
-+
-+ did = dal_divider_range_get_did(divider_ranges, DIVIDER_RANGE_MAX, div);
-+
-+ if (did != INVALID_DID) {
-+ div = dal_divider_range_get_divider(
-+ divider_ranges, DIVIDER_RANGE_MAX, did);
-+
-+ if ((div != INVALID_DIVIDER) &&
-+ (did > DIVIDER_RANGE_01_BASE_DIVIDER_ID))
-+ if (disp_clk_khz > (scaled_vco / div))
-+ div = dal_divider_range_get_divider(
-+ divider_ranges, DIVIDER_RANGE_MAX,
-+ did - 1);
-+
-+ if (div != INVALID_DIVIDER)
-+ disp_clk_khz = scaled_vco / div;
-+
-+ }
-+ /* We need to add 10KHz to this value because the accuracy in VBIOS is
-+ in 10KHz units. So we need to always round the last digit up in order
-+ to reach the next div level.*/
-+ return disp_clk_khz + 10;
-+}
-+
-+static uint32_t calc_single_display_min_clks(
-+ struct display_clock *base,
-+ struct min_clock_params *params,
-+ bool set_clk)
-+{
-+ struct fixed32_32 h_scale_ratio = dal_fixed32_32_one;
-+ struct fixed32_32 v_scale_ratio = dal_fixed32_32_one;
-+ uint32_t pix_clk_khz = 0;
-+ uint32_t lb_source_width = 0;
-+ struct fixed32_32 deep_color_factor;
-+ struct fixed32_32 scaler_efficiency;
-+ struct fixed32_32 v_filter_init;
-+ uint32_t v_filter_init_trunc;
-+ uint32_t num_lines_at_frame_start = 3;
-+ struct fixed32_32 v_filter_init_ceil;
-+ struct fixed32_32 lines_per_lines_out_at_frame_start;
-+ struct fixed32_32 lb_lines_in_per_line_out; /* in middle of the frame*/
-+ uint32_t src_wdth_rnd_to_chunks;
-+ struct fixed32_32 scaling_coeff;
-+ struct fixed32_32 h_blank_granularity_factor =
-+ dal_fixed32_32_one;
-+ struct fixed32_32 fx_disp_clk_mhz;
-+ struct fixed32_32 line_time;
-+ struct fixed32_32 disp_pipe_pix_throughput;
-+ struct fixed32_32 fx_alt_disp_clk_mhz;
-+ uint32_t disp_clk_khz;
-+ uint32_t alt_disp_clk_khz;
-+ struct display_clock_dce112 *disp_clk_110 = DCLCK112_FROM_BASE(base);
-+ uint32_t max_clk_khz = get_validation_clock(base);
-+ bool panning_allowed = false; /* TODO: receive this value from AS */
-+
-+ if (params == NULL) {
-+ dal_logger_write(base->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Invalid input parameter in %s",
-+ __func__);
-+ return 0;
-+ }
-+
-+ deep_color_factor = get_deep_color_factor(params);
-+ scaler_efficiency = get_scaler_efficiency(base->ctx, params);
-+ pix_clk_khz = params->requested_pixel_clock;
-+ lb_source_width = params->source_view.width;
-+
-+ if (0 != params->dest_view.height && 0 != params->dest_view.width) {
-+
-+ h_scale_ratio = dal_fixed32_32_from_fraction(
-+ params->source_view.width,
-+ params->dest_view.width);
-+ v_scale_ratio = dal_fixed32_32_from_fraction(
-+ params->source_view.height,
-+ params->dest_view.height);
-+ } else {
-+ dal_logger_write(base->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Destination height or width is 0!\n");
-+ }
-+
-+ v_filter_init =
-+ dal_fixed32_32_add(
-+ v_scale_ratio,
-+ dal_fixed32_32_add_int(
-+ dal_fixed32_32_div_int(
-+ dal_fixed32_32_mul_int(
-+ v_scale_ratio,
-+ params->timing_info.INTERLACED),
-+ 2),
-+ params->scaling_info.v_taps + 1));
-+ v_filter_init = dal_fixed32_32_div_int(v_filter_init, 2);
-+
-+ v_filter_init_trunc = dal_fixed32_32_floor(v_filter_init);
-+
-+ v_filter_init_ceil = dal_fixed32_32_from_fraction(
-+ v_filter_init_trunc, 2);
-+ v_filter_init_ceil = dal_fixed32_32_from_int(
-+ dal_fixed32_32_ceil(v_filter_init_ceil));
-+ v_filter_init_ceil = dal_fixed32_32_mul_int(v_filter_init_ceil, 2);
-+
-+ lines_per_lines_out_at_frame_start =
-+ dal_fixed32_32_div_int(v_filter_init_ceil,
-+ num_lines_at_frame_start);
-+ lb_lines_in_per_line_out =
-+ get_lb_lines_in_per_line_out(params, v_scale_ratio);
-+
-+ if (panning_allowed)
-+ src_wdth_rnd_to_chunks =
-+ ((lb_source_width - 1) / 128) * 128 + 256;
-+ else
-+ src_wdth_rnd_to_chunks =
-+ ((lb_source_width + 127) / 128) * 128;
-+
-+ scaling_coeff =
-+ dal_fixed32_32_div(
-+ dal_fixed32_32_from_int(params->scaling_info.v_taps),
-+ scaler_efficiency);
-+
-+ if (dal_fixed32_32_le(h_scale_ratio, dal_fixed32_32_one))
-+ scaling_coeff = dal_fixed32_32_max(
-+ dal_fixed32_32_from_int(
-+ dal_fixed32_32_ceil(
-+ dal_fixed32_32_from_fraction(
-+ params->scaling_info.h_taps,
-+ 4))),
-+ dal_fixed32_32_max(
-+ dal_fixed32_32_mul(
-+ scaling_coeff,
-+ h_scale_ratio),
-+ dal_fixed32_32_one));
-+
-+ if (!params->line_buffer_prefetch_enabled &&
-+ dal_fixed32_32_floor(lb_lines_in_per_line_out) != 2 &&
-+ dal_fixed32_32_floor(lb_lines_in_per_line_out) != 4) {
-+ uint32_t line_total_pixel =
-+ params->timing_info.h_total + lb_source_width - 256;
-+ h_blank_granularity_factor = dal_fixed32_32_div(
-+ dal_fixed32_32_from_int(params->timing_info.h_total),
-+ dal_fixed32_32_div(
-+ dal_fixed32_32_from_fraction(
-+ line_total_pixel, 2),
-+ h_scale_ratio));
-+ }
-+
-+ /* Calculate display clock with ramping. Ramping factor is 1.1*/
-+ fx_disp_clk_mhz =
-+ dal_fixed32_32_div_int(
-+ dal_fixed32_32_mul_int(scaling_coeff, 11),
-+ 10);
-+ line_time = dal_fixed32_32_from_fraction(
-+ params->timing_info.h_total * 1000, pix_clk_khz);
-+
-+ disp_pipe_pix_throughput = dal_fixed32_32_mul(
-+ lb_lines_in_per_line_out, h_blank_granularity_factor);
-+ disp_pipe_pix_throughput = dal_fixed32_32_max(
-+ disp_pipe_pix_throughput,
-+ lines_per_lines_out_at_frame_start);
-+ disp_pipe_pix_throughput = dal_fixed32_32_div(dal_fixed32_32_mul_int(
-+ disp_pipe_pix_throughput, src_wdth_rnd_to_chunks),
-+ line_time);
-+
-+ if (0 != params->timing_info.h_total) {
-+ fx_disp_clk_mhz =
-+ dal_fixed32_32_max(
-+ dal_fixed32_32_div_int(
-+ dal_fixed32_32_mul_int(
-+ scaling_coeff, pix_clk_khz),
-+ 1000),
-+ disp_pipe_pix_throughput);
-+ fx_disp_clk_mhz =
-+ dal_fixed32_32_mul(
-+ fx_disp_clk_mhz,
-+ dal_fixed32_32_from_fraction(11, 10));
-+ }
-+
-+ fx_disp_clk_mhz = dal_fixed32_32_max(fx_disp_clk_mhz,
-+ dal_fixed32_32_mul(deep_color_factor,
-+ dal_fixed32_32_from_fraction(11, 10)));
-+
-+ /* Calculate display clock without ramping */
-+ fx_alt_disp_clk_mhz = scaling_coeff;
-+
-+ if (0 != params->timing_info.h_total) {
-+ fx_alt_disp_clk_mhz = dal_fixed32_32_max(
-+ dal_fixed32_32_div_int(dal_fixed32_32_mul_int(
-+ scaling_coeff, pix_clk_khz),
-+ 1000),
-+ dal_fixed32_32_div_int(dal_fixed32_32_mul_int(
-+ disp_pipe_pix_throughput, 105),
-+ 100));
-+ }
-+
-+ if (set_clk && disp_clk_110->ss_on_gpu_pll &&
-+ disp_clk_110->gpu_pll_ss_divider)
-+ fx_alt_disp_clk_mhz = dal_fixed32_32_mul(fx_alt_disp_clk_mhz,
-+ dal_fixed32_32_add_int(
-+ dal_fixed32_32_div_int(
-+ dal_fixed32_32_div_int(
-+ dal_fixed32_32_from_fraction(
-+ disp_clk_110->gpu_pll_ss_percentage,
-+ disp_clk_110->gpu_pll_ss_divider), 100),
-+ 2),
-+ 1));
-+
-+ /* convert to integer */
-+ disp_clk_khz = dal_fixed32_32_round(
-+ dal_fixed32_32_mul_int(fx_disp_clk_mhz, 1000));
-+ alt_disp_clk_khz = dal_fixed32_32_round(
-+ dal_fixed32_32_mul_int(fx_alt_disp_clk_mhz, 1000));
-+
-+ if ((disp_clk_khz > max_clk_khz) && (alt_disp_clk_khz <= max_clk_khz))
-+ disp_clk_khz = alt_disp_clk_khz;
-+
-+ if (set_clk) { /* only compensate clock if we are going to set it.*/
-+ disp_clk_khz = get_actual_required_display_clk(
-+ disp_clk_110, disp_clk_khz);
-+ }
-+
-+ disp_clk_khz = disp_clk_khz > max_clk_khz ? max_clk_khz : disp_clk_khz;
-+
-+ return disp_clk_khz;
-+}
-+
-+static uint32_t calculate_min_clock(
-+ struct display_clock *base,
-+ uint32_t path_num,
-+ struct min_clock_params *params)
-+{
-+ uint32_t i;
-+ uint32_t validation_clk_khz =
-+ get_validation_clock(base);
-+ uint32_t min_clk_khz = validation_clk_khz;
-+ uint32_t max_clk_khz = 0;
-+ struct display_clock_dce112 *dc = DCLCK112_FROM_BASE(base);
-+
-+ if (dc->use_max_disp_clk)
-+ return min_clk_khz;
-+
-+ if (params != NULL) {
-+ uint32_t disp_clk_khz = 0;
-+
-+ for (i = 0; i < path_num; ++i) {
-+
-+ disp_clk_khz = calc_single_display_min_clks(
-+ base, params, true);
-+
-+ /* update the max required clock found*/
-+ if (disp_clk_khz > max_clk_khz)
-+ max_clk_khz = disp_clk_khz;
-+
-+ params++;
-+ }
-+ }
-+
-+ min_clk_khz = max_clk_khz;
-+
-+ if (min_clk_khz > validation_clk_khz)
-+ min_clk_khz = validation_clk_khz;
-+ else if (min_clk_khz < base->min_display_clk_threshold_khz)
-+ min_clk_khz = base->min_display_clk_threshold_khz;
-+
-+ if (dc->use_max_disp_clk)
-+ min_clk_khz = get_validation_clock(base);
-+
-+ return min_clk_khz;
-+}
-+
-+static bool display_clock_integrated_info_construct(
-+ struct display_clock_dce112 *disp_clk,
-+ struct adapter_service *as)
-+{
-+ struct integrated_info info;
-+ uint32_t i;
-+ struct display_clock *base = &disp_clk->disp_clk_base;
-+
-+ memset(&info, 0, sizeof(struct integrated_info));
-+
-+ disp_clk->dentist_vco_freq_khz = info.dentist_vco_freq;
-+ if (disp_clk->dentist_vco_freq_khz == 0)
-+ disp_clk->dentist_vco_freq_khz = 3600000;
-+
-+ disp_clk->crystal_freq_khz = 100000;
-+
-+ base->min_display_clk_threshold_khz =
-+ disp_clk->dentist_vco_freq_khz / 64;
-+
-+ /*update the maximum display clock for each power state*/
-+ for (i = 0; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
-+ enum clocks_state clk_state = CLOCKS_STATE_INVALID;
-+
-+ switch (i) {
-+ case 0:
-+ clk_state = CLOCKS_STATE_ULTRA_LOW;
-+ break;
-+
-+ case 1:
-+ clk_state = CLOCKS_STATE_LOW;
-+ break;
-+
-+ case 2:
-+ clk_state = CLOCKS_STATE_NOMINAL;
-+ break;
-+
-+ case 3:
-+ clk_state = CLOCKS_STATE_PERFORMANCE;
-+ break;
-+
-+ default:
-+ clk_state = CLOCKS_STATE_INVALID;
-+ break;
-+ }
-+
-+ /*Do not allow bad VBIOS/SBIOS to override with invalid values,
-+ * check for > 100MHz*/
-+ if (info.disp_clk_voltage[i].max_supported_clk >= 100000) {
-+ max_clks_by_state[clk_state].display_clk_khz =
-+ info.disp_clk_voltage[i].max_supported_clk;
-+ }
-+ }
-+ disp_clk->dfs_bypass_enabled =
-+ dal_adapter_service_is_dfs_bypass_enabled(as);
-+ disp_clk->use_max_disp_clk =
-+ dal_adapter_service_is_feature_supported(
-+ FEATURE_USE_MAX_DISPLAY_CLK);
-+
-+ return true;
-+}
-+
-+static uint32_t get_clock(struct display_clock *dc)
-+{
-+ uint32_t disp_clock = get_validation_clock(dc);
-+ uint32_t target_div = INVALID_DIVIDER;
-+ uint32_t addr = mmDENTIST_DISPCLK_CNTL;
-+ uint32_t value = 0;
-+ uint32_t field = 0;
-+ struct display_clock_dce112 *disp_clk = DCLCK112_FROM_BASE(dc);
-+
-+ /* 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 enum clocks_state get_required_clocks_state(
-+ struct display_clock *dc,
-+ struct state_dependent_clocks *req_clocks)
-+{
-+ int32_t i;
-+ struct display_clock_dce112 *disp_clk = DCLCK112_FROM_BASE(dc);
-+ enum clocks_state low_req_clk = disp_clk->max_clks_state;
-+
-+ if (!req_clocks) {
-+ /* NULL pointer*/
-+ dal_logger_write(dc->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "%s: Invalid parameter",
-+ __func__);
-+ return CLOCKS_STATE_INVALID;
-+ }
-+
-+ /* Iterate from highest supported to lowest valid state, and update
-+ * lowest RequiredState with the lowest state that satisfies
-+ * all required clocks
-+ */
-+ for (i = disp_clk->max_clks_state; i >= CLOCKS_STATE_ULTRA_LOW; --i) {
-+ if ((req_clocks->display_clk_khz <=
-+ max_clks_by_state[i].display_clk_khz) &&
-+ (req_clocks->pixel_clk_khz <=
-+ max_clks_by_state[i].pixel_clk_khz))
-+ low_req_clk = i;
-+ }
-+ return low_req_clk;
-+}
-+
-+static void set_clock(
-+ struct display_clock *base,
-+ uint32_t requested_clk_khz)
-+{
-+ struct bp_set_dce_clock_parameters dce_clk_params;
-+ struct display_clock_dce112 *dc = DCLCK112_FROM_BASE(base);
-+ struct dc_bios *bp = dal_adapter_service_get_bios_parser(base->as);
-+
-+ /* Prepare to program display clock*/
-+ memset(&dce_clk_params, 0, sizeof(dce_clk_params));
-+
-+ dce_clk_params.target_clock_frequency = requested_clk_khz;
-+ dce_clk_params.pll_id = dc->disp_clk_base.id;
-+ dce_clk_params.clock_type = DCECLOCK_TYPE_DISPLAY_CLOCK;
-+
-+ bp->funcs->set_dce_clock(bp, &dce_clk_params);
-+
-+ /* from power down, we need mark the clock state as ClocksStateNominal
-+ * from HWReset, so when resume we will call pplib voltage regulator.*/
-+ if (requested_clk_khz == 0)
-+ base->cur_min_clks_state = CLOCKS_STATE_NOMINAL;
-+
-+ /*Program DP ref Clock*/
-+ /*VBIOS will determine DPREFCLK frequency, so we don't set it*/
-+ dce_clk_params.target_clock_frequency = 0;
-+ dce_clk_params.clock_type = DCECLOCK_TYPE_DPREFCLK;
-+ dce_clk_params.flags.USE_GENLOCK_AS_SOURCE_FOR_DPREFCLK =
-+ (dce_clk_params.pll_id == CLOCK_SOURCE_COMBO_DISPLAY_PLL0);
-+
-+ bp->funcs->set_dce_clock(bp, &dce_clk_params);
-+}
-+
-+static void set_clock_state(
-+ struct display_clock *dc,
-+ struct display_clock_state clk_state)
-+{
-+ struct display_clock_dce112 *disp_clk = DCLCK112_FROM_BASE(dc);
-+
-+ disp_clk->clock_state = clk_state;
-+}
-+
-+static struct display_clock_state get_clock_state(
-+ struct display_clock *dc)
-+{
-+ struct display_clock_dce112 *disp_clk = DCLCK112_FROM_BASE(dc);
-+
-+ return disp_clk->clock_state;
-+}
-+
-+static uint32_t get_dfs_bypass_threshold(struct display_clock *dc)
-+{
-+ return dce112_DFS_BYPASS_THRESHOLD_KHZ;
-+}
-+
-+static const struct display_clock_funcs funcs = {
-+ .destroy = destroy,
-+ .calculate_min_clock = calculate_min_clock,
-+ .get_clock = get_clock,
-+ .get_clock_state = get_clock_state,
-+ .get_dfs_bypass_threshold = get_dfs_bypass_threshold,
-+ .get_dp_ref_clk_frequency = get_dp_ref_clk_frequency,
-+ .get_min_clocks_state = get_min_clocks_state,
-+ .get_required_clocks_state = get_required_clocks_state,
-+ .get_validation_clock = get_validation_clock,
-+ .set_clock = set_clock,
-+ .set_clock_state = set_clock_state,
-+ .set_dp_ref_clock_source = NULL,
-+ .set_min_clocks_state = set_min_clocks_state,
-+ .store_max_clocks_state = store_max_clocks_state,
-+ .validate = NULL,
-+};
-+
-+static bool dal_display_clock_dce112_construct(
-+ struct display_clock_dce112 *dc112,
-+ struct dc_context *ctx,
-+ struct adapter_service *as)
-+{
-+ struct display_clock *dc_base = &dc112->disp_clk_base;
-+
-+ if (NULL == as)
-+ return false;
-+
-+ if (!dal_display_clock_construct_base(dc_base, ctx, as))
-+ return false;
-+
-+ dc_base->funcs = &funcs;
-+
-+ dc112->dfs_bypass_disp_clk = 0;
-+
-+ if (!display_clock_integrated_info_construct(dc112, as))
-+ dal_logger_write(dc_base->ctx->logger,
-+ LOG_MAJOR_WARNING,
-+ LOG_MINOR_COMPONENT_GPU,
-+ "Cannot obtain VBIOS integrated info\n");
-+
-+ dc112->gpu_pll_ss_percentage = 0;
-+ dc112->gpu_pll_ss_divider = 1000;
-+ dc112->ss_on_gpu_pll = false;
-+
-+ dc_base->id = CLOCK_SOURCE_ID_DFS;
-+/* Initially set max clocks state to nominal. This should be updated by
-+ * via a pplib call to DAL IRI eventually calling a
-+ * DisplayEngineClock_dce112::StoreMaxClocksState(). This call will come in
-+ * on PPLIB init. This is from DCE5x. in case HW wants to use mixed method.*/
-+ dc112->max_clks_state = CLOCKS_STATE_NOMINAL;
-+
-+ dc112->disp_clk_base.min_display_clk_threshold_khz =
-+ dc112->crystal_freq_khz;
-+
-+ if (dc112->disp_clk_base.min_display_clk_threshold_khz <
-+ (dc112->dentist_vco_freq_khz / 62))
-+ dc112->disp_clk_base.min_display_clk_threshold_khz =
-+ (dc112->dentist_vco_freq_khz / 62);
-+
-+ dal_divider_range_construct(
-+ &divider_ranges[DIVIDER_RANGE_01],
-+ DIVIDER_RANGE_01_START,
-+ DIVIDER_RANGE_01_STEP_SIZE,
-+ DIVIDER_RANGE_01_BASE_DIVIDER_ID,
-+ DIVIDER_RANGE_02_BASE_DIVIDER_ID);
-+ dal_divider_range_construct(
-+ &divider_ranges[DIVIDER_RANGE_02],
-+ DIVIDER_RANGE_02_START,
-+ DIVIDER_RANGE_02_STEP_SIZE,
-+ DIVIDER_RANGE_02_BASE_DIVIDER_ID,
-+ DIVIDER_RANGE_03_BASE_DIVIDER_ID);
-+ dal_divider_range_construct(
-+ &divider_ranges[DIVIDER_RANGE_03],
-+ DIVIDER_RANGE_03_START,
-+ DIVIDER_RANGE_03_STEP_SIZE,
-+ DIVIDER_RANGE_03_BASE_DIVIDER_ID,
-+ DIVIDER_RANGE_MAX_DIVIDER_ID);
-+
-+ {
-+ uint32_t ss_info_num =
-+ dal_adapter_service_get_ss_info_num(
-+ as,
-+ AS_SIGNAL_TYPE_GPU_PLL);
-+
-+ if (ss_info_num) {
-+ struct spread_spectrum_info info;
-+ bool result;
-+
-+ memset(&info, 0, sizeof(info));
-+
-+ result =
-+ dal_adapter_service_get_ss_info(
-+ as,
-+ AS_SIGNAL_TYPE_GPU_PLL,
-+ 0,
-+ &info);
-+
-+ /* Based on VBIOS, VBIOS will keep entry for GPU PLL SS
-+ * even if SS not enabled and in that case
-+ * SSInfo.spreadSpectrumPercentage !=0 would be sign
-+ * that SS is enabled
-+ */
-+ if (result && info.spread_spectrum_percentage != 0) {
-+ dc112->ss_on_gpu_pll = true;
-+ dc112->gpu_pll_ss_divider =
-+ info.spread_percentage_divider;
-+
-+ if (info.type.CENTER_MODE == 0) {
-+ /* Currently for DP Reference clock we
-+ * need only SS percentage for
-+ * downspread */
-+ dc112->gpu_pll_ss_percentage =
-+ info.spread_spectrum_percentage;
-+ }
-+ }
-+
-+ }
-+ }
-+
-+ dc112->use_max_disp_clk = true;
-+
-+ return true;
-+}
-+
-+/*****************************************************************************
-+ * public functions
-+ *****************************************************************************/
-+
-+struct display_clock *dal_display_clock_dce112_create(
-+ struct dc_context *ctx,
-+ struct adapter_service *as)
-+{
-+ struct display_clock_dce112 *dc112;
-+
-+ dc112 = dm_alloc(sizeof(struct display_clock_dce112));
-+
-+ if (dc112 == NULL)
-+ return NULL;
-+
-+ if (dal_display_clock_dce112_construct(dc112, ctx, as))
-+ return &dc112->disp_clk_base;
-+
-+ dm_free(dc112);
-+
-+ return NULL;
-+}
-diff --git a/drivers/gpu/drm/amd/dal/dc/gpu/dce112/display_clock_dce112.h b/drivers/gpu/drm/amd/dal/dc/gpu/dce112/display_clock_dce112.h
-new file mode 100644
-index 0000000..02fc67a
---- /dev/null
-+++ b/drivers/gpu/drm/amd/dal/dc/gpu/dce112/display_clock_dce112.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_DISPLAY_CLOCK_DCE112_H__
-+#define __DAL_DISPLAY_CLOCK_DCE112_H__
-+
-+#include "gpu/display_clock.h"
-+
-+struct display_clock_dce112 {
-+ struct display_clock disp_clk_base;
-+ /* Max display block clocks state*/
-+ enum clocks_state max_clks_state;
-+ bool use_max_disp_clk;
-+ uint32_t crystal_freq_khz;
-+ uint32_t dentist_vco_freq_khz;
-+ /* Cache the status of DFS-bypass feature*/
-+ bool dfs_bypass_enabled;
-+ /* GPU PLL SS percentage (if down-spread enabled) */
-+ uint32_t gpu_pll_ss_percentage;
-+ /* GPU PLL SS percentage Divider (100 or 1000) */
-+ uint32_t gpu_pll_ss_divider;
-+ /* Flag for Enabled SS on GPU PLL */
-+ bool ss_on_gpu_pll;
-+ /* Cache the display clock returned by VBIOS if DFS-bypass is enabled.
-+ * This is basically "Crystal Frequency In KHz" (XTALIN) frequency */
-+ uint32_t dfs_bypass_disp_clk;
-+ struct display_clock_state clock_state;
-+};
-+
-+#define DCLCK112_FROM_BASE(dc_base) \
-+ container_of(dc_base, struct display_clock_dce112, disp_clk_base)
-+
-+#endif /* __DAL_DISPLAY_CLOCK_DCE112_H__ */
-diff --git a/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c b/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c
-index 47e7922..2d394cf 100644
---- a/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c
-+++ b/drivers/gpu/drm/amd/dal/dc/i2caux/i2caux.c
-@@ -88,10 +88,13 @@ struct i2caux *dal_i2caux_create(
- return dal_i2caux_dce80_create(as, ctx);
- #endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
-+ case DCE_VERSION_11_0:
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ case DCE_VERSION_11_2:
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
- case DCE_VERSION_10_0:
- #endif
-- case DCE_VERSION_11_0:
- return dal_i2caux_dce110_create(as, ctx);
- #endif
- default:
-diff --git a/drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h b/drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h
-index d6a599c..da00b2e 100644
---- a/drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h
-+++ b/drivers/gpu/drm/amd/dal/dc/inc/bandwidth_calcs.h
-@@ -505,7 +505,9 @@ struct bw_calcs_output {
-
- enum bw_calcs_version {
- BW_CALCS_VERSION_INVALID,
-- BW_CALCS_VERSION_CARRIZO
-+ BW_CALCS_VERSION_CARRIZO,
-+ BW_CALCS_VERSION_ELLESMERE,
-+ BW_CALCS_VERSION_BAFFIN
- };
-
- /**
-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 cde34ce..bfffa8e 100644
---- a/drivers/gpu/drm/amd/dal/dc/irq/irq_service.c
-+++ b/drivers/gpu/drm/amd/dal/dc/irq/irq_service.c
-@@ -65,6 +65,10 @@ struct irq_service *dal_irq_service_create(
- case DCE_VERSION_10_0:
- return dal_irq_service_dce110_create(init_data);
- #endif
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ case DCE_VERSION_11_2:
-+ return dal_irq_service_dce110_create(init_data);
-+#endif
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
- case DCE_VERSION_11_0:
- return dal_irq_service_dce110_create(init_data);
-diff --git a/drivers/gpu/drm/amd/dal/include/dal_asic_id.h b/drivers/gpu/drm/amd/dal/include/dal_asic_id.h
-index d8c4cd1..4cb6a9f 100644
---- a/drivers/gpu/drm/amd/dal/include/dal_asic_id.h
-+++ b/drivers/gpu/drm/amd/dal/include/dal_asic_id.h
-@@ -83,11 +83,25 @@
- #define VI_TONGA_P_A1 21
- #define VI_FIJI_P_A0 60
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+/* DCE112 */
-+#define VI_POLARIS10_P_A0 80
-+#define VI_POLARIS11_M_A0 90
-+#endif
-+
-+#define VI_UNKNOWN 0xFF
-+
- #define ASIC_REV_IS_TONGA_P(eChipRev) ((eChipRev >= VI_TONGA_P_A0) && \
- (eChipRev < 40))
- #define ASIC_REV_IS_FIJI_P(eChipRev) ((eChipRev >= VI_FIJI_P_A0) && \
- (eChipRev < 80))
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+#define ASIC_REV_IS_POLARIS10_P(eChipRev) ((eChipRev >= VI_POLARIS10_P_A0) && \
-+ (eChipRev < VI_POLARIS11_M_A0))
-+#define ASIC_REV_IS_POLARIS11_M(eChipRev) (eChipRev >= VI_POLARIS11_M_A0)
-+#endif
-+
- /* DCE11 */
- #define CZ_CARRIZO_A0 0x01
-
-diff --git a/drivers/gpu/drm/amd/dal/include/dal_types.h b/drivers/gpu/drm/amd/dal/include/dal_types.h
-index bcf83e9..21ee669 100644
---- a/drivers/gpu/drm/amd/dal/include/dal_types.h
-+++ b/drivers/gpu/drm/amd/dal/include/dal_types.h
-@@ -43,6 +43,9 @@ enum dce_version {
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
- DCE_VERSION_11_0,
- #endif
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+ DCE_VERSION_11_2,
-+#endif
- DCE_VERSION_MAX,
- };
-
-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 a625e24..317ce3b 100644
---- a/drivers/gpu/drm/amd/dal/include/display_clock_interface.h
-+++ b/drivers/gpu/drm/amd/dal/include/display_clock_interface.h
-@@ -131,6 +131,12 @@ struct display_clock_state {
-
- struct display_clock;
-
-+#if defined(CONFIG_DRM_AMD_DAL_DCE11_2)
-+struct display_clock *dal_display_clock_dce112_create(
-+ struct dc_context *ctx,
-+ struct adapter_service *as);
-+#endif
-+
- #if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
- struct display_clock *dal_display_clock_dce110_create(
- struct dc_context *ctx,
---
-2.7.4
-