Provides information about ASIC features and capabilities. Also provides
access to ASIC resources such as VBIOS, GPIO and I2cAux Manager

Signed-off-by: Harry Wentland <harry.wentland at amd.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/amd/dal/dc/adapter/Makefile        |   24 +
 .../gpu/drm/amd/dal/dc/adapter/adapter_service.c   | 2089 ++++++++++++++++++++
 .../gpu/drm/amd/dal/dc/adapter/adapter_service.h   |   71 +
 .../adapter/dce110/hw_ctx_adapter_service_dce110.c |  304 +++
 .../adapter/dce110/hw_ctx_adapter_service_dce110.h |   40 +
 .../diagnostics/hw_ctx_adapter_service_diag.c      |  133 ++
 .../diagnostics/hw_ctx_adapter_service_diag.h      |   33 +
 .../amd/dal/dc/adapter/hw_ctx_adapter_service.c    |  164 ++
 .../amd/dal/dc/adapter/hw_ctx_adapter_service.h    |   86 +
 .../drm/amd/dal/dc/adapter/wireless_data_source.c  |  208 ++
 .../drm/amd/dal/dc/adapter/wireless_data_source.h  |   80 +
 11 files changed, 3232 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/Makefile
 create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.h
 create mode 100644 
drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.c
 create mode 100644 
drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.h
 create mode 100644 
drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.c
 create mode 100644 
drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.h

diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/Makefile 
b/drivers/gpu/drm/amd/dal/dc/adapter/Makefile
new file mode 100644
index 000000000000..2c6ca7a513bd
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/adapter/Makefile
@@ -0,0 +1,24 @@
+#
+# Makefile for the 'adapter' sub-component of DAL.
+# It provides the control and status of HW adapter.
+
+ADAPTER = adapter_service.o hw_ctx_adapter_service.o wireless_data_source.o
+
+AMD_DAL_ADAPTER = $(addprefix $(AMDDALPATH)/dc/adapter/,$(ADAPTER))
+
+AMD_DAL_FILES += $(AMD_DAL_ADAPTER)
+
+
+###############################################################################
+# DCE 11x
+###############################################################################
+
+ifdef CONFIG_DRM_AMD_DAL_DCE11_0
+AMD_DAL_FILES += 
$(AMDDALPATH)/dc/adapter/dce110/hw_ctx_adapter_service_dce110.o
+endif
+
+###############################################################################
+# FPGA Diagnositcs
+###############################################################################
+
+AMD_DAL_FILES += 
$(AMDDALPATH)/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.o
diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c 
b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c
new file mode 100644
index 000000000000..dd2f931fe9a1
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c
@@ -0,0 +1,2089 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 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_bios_types.h"
+
+#include "include/adapter_service_interface.h"
+#include "include/i2caux_interface.h"
+#include "include/asic_capability_types.h"
+#include "include/gpio_service_interface.h"
+#include "include/asic_capability_interface.h"
+#include "include/logger_interface.h"
+
+#include "adapter_service.h"
+
+#include "hw_ctx_adapter_service.h"
+#include "wireless_data_source.h"
+
+#include "atom.h"
+
+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
+#include "dce110/hw_ctx_adapter_service_dce110.h"
+#endif
+
+#include "diagnostics/hw_ctx_adapter_service_diag.h"
+
+/*
+ * Adapter service feature entry table.
+ *
+ * This is an array of features that is used to generate feature set. Each
+ * entry consists three element:
+ *
+ * Feature name, default value, and if this feature is a boolean type. A
+ * feature can only be a boolean or int type.
+ *
+ * Example 1: a boolean type feature
+ * FEATURE_ENABLE_HW_EDID_POLLING, false, true
+ *
+ * First element is feature name: EATURE_ENABLE_HW_EDID_POLLING, it has a
+ * default value 0, and it is a boolean feature.
+ *
+ * Example 2: an int type feature
+ * FEATURE_DCP_PROGRAMMING_WA, 0x1FF7, false
+ *
+ * In this case, the default value is 0x1FF7 and not a boolean type, which
+ * makes it an int type.
+ */
+
+static struct feature_source_entry feature_entry_table[] = {
+       /* Feature name | default value | is boolean type */
+       {FEATURE_ENABLE_HW_EDID_POLLING, false, true},
+       {FEATURE_DP_SINK_DETECT_POLL_DATA_PIN, false, true},
+       {FEATURE_UNDERFLOW_INTERRUPT, false, true},
+       {FEATURE_ALLOW_WATERMARK_ADJUSTMENT, false, true},
+       {FEATURE_LIGHT_SLEEP, false, true},
+       {FEATURE_DCP_DITHER_FRAME_RANDOM_ENABLE, false, true},
+       {FEATURE_DCP_DITHER_RGB_RANDOM_ENABLE, false, true},
+       {FEATURE_DCP_DITHER_HIGH_PASS_RANDOM_ENABLE, false, true},
+       {FEATURE_LINE_BUFFER_ENHANCED_PIXEL_DEPTH, false, true},
+       {FEATURE_MAXIMIZE_URGENCY_WATERMARKS, false, true},
+       {FEATURE_MAXIMIZE_STUTTER_MARKS, false, true},
+       {FEATURE_MAXIMIZE_NBP_MARKS, false, true},
+       /*
+        * We meet HW I2C issue when test S3 resume on KB.
+        * An EPR is created for debug the issue.
+        * Make Test has already been implemented
+        * with HW I2C. The work load for revert back to SW I2C in make test
+        * is big. Below is workaround for this issue.
+        * Driver uses SW I2C.
+        * Make Test uses HW I2C.
+        */
+       {FEATURE_RESTORE_USAGE_I2C_SW_ENGINE, false, true},
+       {FEATURE_USE_MAX_DISPLAY_CLK, false, true},
+       {FEATURE_ALLOW_EDP_RESOURCE_SHARING, false, true},
+       {FEATURE_SUPPORT_DP_YUV, false, true},
+       {FEATURE_SUPPORT_DP_Y_ONLY, false, true},
+       {FEATURE_DISABLE_DP_GTC_SYNC, true, true},
+       {FEATURE_MODIFY_TIMINGS_FOR_WIRELESS, false, true},
+       {FEATURE_DCP_BIT_DEPTH_REDUCTION_MODE, 0, false},
+       {FEATURE_DCP_DITHER_MODE, 0, false},
+       {FEATURE_DCP_PROGRAMMING_WA, 0, false},
+       {FEATURE_NO_HPD_LOW_POLLING_VCC_OFF, false, true},
+       {FEATURE_ENABLE_DFS_BYPASS, false, true},
+       {FEATURE_WIRELESS_FULL_TIMING_ADJUSTMENT, false, true},
+       {FEATURE_MAX_COFUNC_NON_DP_DISPLAYS, 2, false},
+       {FEATURE_WIRELESS_LIMIT_720P, false, true},
+       {FEATURE_MODIFY_TIMINGS_FOR_WIRELESS, false, true},
+       {FEATURE_SUPPORTED_HDMI_CONNECTION_NUM, 0, false},
+       {FEATURE_DETECT_REQUIRE_HPD_HIGH, false, true},
+       {FEATURE_NO_HPD_LOW_POLLING_VCC_OFF, false, true},
+       {FEATURE_LB_HIGH_RESOLUTION, false, true},
+       {FEATURE_MAX_CONTROLLER_NUM, 0, false},
+       {FEATURE_DRR_SUPPORT, AS_DRR_SUPPORT_ENABLED, false},
+       {FEATURE_STUTTER_MODE, 15, false},
+       {FEATURE_DP_DISPLAY_FORCE_SS_ENABLE, false, true},
+       {FEATURE_REPORT_CE_MODE_ONLY, false, true},
+       {FEATURE_ALLOW_OPTIMIZED_MODE_AS_DEFAULT, false, true},
+       {FEATURE_DDC_READ_FORCE_REPEATED_START, false, true},
+       {FEATURE_FORCE_TIMING_RESYNC, false, true},
+       {FEATURE_TMDS_DISABLE_DITHERING, false, true},
+       {FEATURE_HDMI_DISABLE_DITHERING, false, true},
+       {FEATURE_DP_DISABLE_DITHERING, false, true},
+       {FEATURE_EMBEDDED_DISABLE_DITHERING, true, true},
+       {FEATURE_ALLOW_SELF_REFRESH, false, true},
+       {FEATURE_ALLOW_DYNAMIC_PIXEL_ENCODING_CHANGE, false, true},
+       {FEATURE_ALLOW_HSYNC_VSYNC_ADJUSTMENT, false, true},
+       {FEATURE_FORCE_PSR, false, true},
+       {FEATURE_PSR_SETUP_TIME_TEST, 0, false},
+       {FEATURE_POWER_GATING_PIPE_IN_TILE, true, true},
+       {FEATURE_POWER_GATING_LB_PORTION, true, true},
+       {FEATURE_PREFER_3D_TIMING, false, true},
+       {FEATURE_VARI_BRIGHT_ENABLE, true, true},
+       {FEATURE_PSR_ENABLE, false, true},
+       {FEATURE_WIRELESS_ENABLE_COMPRESSED_AUDIO, false, true},
+       {FEATURE_WIRELESS_INCLUDE_UNVERIFIED_TIMINGS, true, true},
+       {FEATURE_EDID_STRESS_READ, false, true},
+       {FEATURE_DP_FRAME_PACK_STEREO3D, false, true},
+       {FEATURE_DISPLAY_PREFERRED_VIEW, 0, false},
+       {FEATURE_ALLOW_HDMI_WITHOUT_AUDIO, false, true},
+       {FEATURE_ABM_2_0, false, true},
+       {FEATURE_SUPPORT_MIRABILIS, false, true},
+       {FEATURE_OPTIMIZATION, 0xFFFF, false},
+       {FEATURE_PERF_MEASURE, 0, false},
+       {FEATURE_MIN_BACKLIGHT_LEVEL, 0, false},
+       {FEATURE_MAX_BACKLIGHT_LEVEL, 255, false},
+       {FEATURE_LOAD_DMCU_FIRMWARE, true, true},
+       {FEATURE_DISABLE_AZ_CLOCK_GATING, false, true},
+       {FEATURE_ENABLE_GPU_SCALING, false, true},
+       {FEATURE_DONGLE_SINK_COUNT_CHECK, true, true},
+       {FEATURE_INSTANT_UP_SCALE_DOWN_SCALE, false, true},
+       {FEATURE_TILED_DISPLAY, false, true},
+       {FEATURE_PREFERRED_ABM_CONFIG_SET, 0, false},
+       {FEATURE_CHANGE_SW_I2C_SPEED, 50, false},
+       {FEATURE_CHANGE_HW_I2C_SPEED, 50, false},
+       {FEATURE_CHANGE_I2C_SPEED_CONTROL, false, true},
+       {FEATURE_DEFAULT_PSR_LEVEL, 0, false},
+       {FEATURE_MAX_CLOCK_SOURCE_NUM, 0, false},
+       {FEATURE_REPORT_SINGLE_SELECTED_TIMING, false, true},
+       {FEATURE_ALLOW_HDMI_HIGH_CLK_DP_DONGLE, true, true},
+       {FEATURE_SUPPORT_EXTERNAL_PANEL_DRR, false, true},
+       {FEATURE_LVDS_SAFE_PIXEL_CLOCK_RANGE, 0, false},
+       {FEATURE_ABM_CONFIG, 0, false},
+       {FEATURE_WIRELESS_ENABLE, false, true},
+       {FEATURE_ALLOW_DIRECT_MEMORY_ACCESS_TRIG, false, true},
+       {FEATURE_FORCE_STATIC_SCREEN_EVENT_TRIGGERS, 0, false},
+       {FEATURE_USE_PPLIB, true, true},
+       {FEATURE_DISABLE_LPT_SUPPORT, false, true},
+       {FEATURE_DUMMY_FBC_BACKEND, false, true},
+       {FEATURE_DPMS_AUDIO_ENDPOINT_CONTROL, true, true},
+       {FEATURE_DISABLE_FBC_COMP_CLK_GATE, false, true},
+       {FEATURE_PIXEL_PERFECT_OUTPUT, false, true},
+       {FEATURE_8BPP_SUPPORTED, false, true}
+};
+
+
+/* Stores entire ASIC features by sets */
+uint32_t adapter_feature_set[FEATURE_MAXIMUM/32];
+
+enum {
+       LEGACY_MAX_NUM_OF_CONTROLLERS = 2,
+       DEFAULT_NUM_COFUNC_NON_DP_DISPLAYS = 2
+};
+
+/*
+ * get_feature_entries_num
+ *
+ * Get number of feature entries
+ */
+static inline uint32_t get_feature_entries_num(void)
+{
+       return ARRAY_SIZE(feature_entry_table);
+}
+
+static void get_platform_info_methods(
+               struct adapter_service *as)
+{
+       struct platform_info_params params;
+       uint32_t mask = 0;
+
+       params.data = &mask;
+       params.method = PM_GET_AVAILABLE_METHODS;
+
+       if (dm_get_platform_info(as->ctx, &params))
+               as->platform_methods_mask = mask;
+
+
+}
+
+static void initialize_backlight_caps(
+               struct adapter_service *as)
+{
+       struct firmware_info fw_info;
+       struct embedded_panel_info panel_info;
+       struct platform_info_ext_brightness_caps caps;
+       struct platform_info_params params;
+       bool custom_curve_present = false;
+       bool custom_min_max_present = false;
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       if (!(PM_GET_EXTENDED_BRIGHNESS_CAPS & as->platform_methods_mask)) {
+                       dal_logger_write(as->ctx->logger,
+                                       LOG_MAJOR_BACKLIGHT,
+                                       LOG_MINOR_BACKLIGHT_BRIGHTESS_CAPS,
+                                       "This method is not supported\n");
+                       return;
+       }
+
+       if (dcb->funcs->get_firmware_info(dcb, &fw_info) != BP_RESULT_OK ||
+               dcb->funcs->get_embedded_panel_info(dcb, &panel_info) != 
BP_RESULT_OK)
+               return;
+
+       params.data = &caps;
+       params.method = PM_GET_EXTENDED_BRIGHNESS_CAPS;
+
+       if (dm_get_platform_info(as->ctx, &params)) {
+               as->ac_level_percentage = caps.basic_caps.ac_level_percentage;
+               as->dc_level_percentage = caps.basic_caps.dc_level_percentage;
+               custom_curve_present = (caps.data_points_num > 0);
+               custom_min_max_present = true;
+       } else
+               return;
+       /* Choose minimum backlight level base on priority:
+        * extended caps,VBIOS,default */
+       if (custom_min_max_present)
+               as->backlight_8bit_lut[0] = caps.min_input_signal;
+
+       else if (fw_info.min_allowed_bl_level > 0)
+               as->backlight_8bit_lut[0] = fw_info.min_allowed_bl_level;
+
+       else
+               as->backlight_8bit_lut[0] = DEFAULT_MIN_BACKLIGHT;
+
+       /* Choose maximum backlight level base on priority:
+        * extended caps,default */
+       if (custom_min_max_present)
+               as->backlight_8bit_lut[100] = caps.max_input_signal;
+
+       else
+               as->backlight_8bit_lut[100] = DEFAULT_MAX_BACKLIGHT;
+
+       if (as->backlight_8bit_lut[100] > ABSOLUTE_BACKLIGHT_MAX)
+               as->backlight_8bit_lut[100] = ABSOLUTE_BACKLIGHT_MAX;
+
+       if (as->backlight_8bit_lut[0] > as->backlight_8bit_lut[100])
+               as->backlight_8bit_lut[0] = as->backlight_8bit_lut[100];
+
+       if (custom_curve_present) {
+               uint16_t index = 1;
+               uint16_t i;
+               uint16_t num_of_data_points = (caps.data_points_num <= 99 ?
+                               caps.data_points_num : 99);
+               /* Filling translation table from data points -
+                * between every two provided data points we
+                * lineary interpolate missing values
+                */
+               for (i = 0 ; i < num_of_data_points; i++) {
+                       uint16_t luminance = caps.data_points[i].luminance;
+                       uint16_t signal_level =
+                                       caps.data_points[i].signal_level;
+
+                       if (signal_level < as->backlight_8bit_lut[0])
+                               signal_level = as->backlight_8bit_lut[0];
+
+                       if (signal_level > as->backlight_8bit_lut[100])
+                               signal_level = as->backlight_8bit_lut[100];
+
+                       /* Lineary interpolate missing values */
+                       if (index < luminance) {
+                               uint16_t base_value =
+                                               as->backlight_8bit_lut[index-1];
+                               uint16_t delta_signal =
+                                               signal_level - base_value;
+                               uint16_t delta_luma = luminance - index + 1;
+                               uint16_t step = delta_signal;
+
+                               for (; index < luminance ; index++) {
+                                       as->backlight_8bit_lut[index] =
+                                                       base_value +
+                                                       (step / delta_luma);
+                                       step += delta_signal;
+                               }
+                       }
+                       /* Now [index == luminance], so we can add
+                        * data point to the translation table */
+                       as->backlight_8bit_lut[index++] = signal_level;
+               }
+               /* Complete the final segment of interpolation -
+                * between last datapoint and maximum value */
+               if (index < 100) {
+                       uint16_t base_value = as->backlight_8bit_lut[index-1];
+                       uint16_t delta_signal =
+                                       as->backlight_8bit_lut[100]-base_value;
+                       uint16_t delta_luma = 100 - index + 1;
+                       uint16_t step = delta_signal;
+
+                       for (; index < 100 ; index++) {
+                               as->backlight_8bit_lut[index] = base_value +
+                                               (step / delta_luma);
+                               step += delta_signal;
+                       }
+               }
+       }
+       /* build backlight translation table based on default curve */
+       else {
+               /* Default backlight curve can be defined by
+                * polinomial F(x) = A(x*x) + Bx + C.
+                * Backlight curve should always  satisfy
+                * F(0) = min, F(100) = max, so polinomial coefficients are:
+                * A is 0.0255 - B/100 - min/10000 -
+                * (255-max)/10000 = (max - min)/10000 - B/100
+                * B is adjustable factor to modify the curve.
+                * Bigger B results in less concave curve.
+                * B range is [0..(max-min)/100]
+                * C is backlight minimum
+                */
+               uint16_t delta = as->backlight_8bit_lut[100] -
+                               as->backlight_8bit_lut[0];
+               uint16_t coeffc = as->backlight_8bit_lut[0];
+               uint16_t coeffb = (BACKLIGHT_CURVE_COEFFB < delta ?
+                               BACKLIGHT_CURVE_COEFFB : delta);
+               uint16_t coeffa = delta - coeffb;
+               uint16_t i;
+               uint32_t temp;
+
+               for (i = 1; i < 100 ; i++) {
+                       temp = (coeffa * i * i) / BACKLIGHT_CURVE_COEFFA_FACTOR;
+                       as->backlight_8bit_lut[i] = temp + (coeffb * i) /
+                                       BACKLIGHT_CURVE_COEFFB_FACTOR + coeffc;
+               }
+       }
+       as->backlight_caps_initialized = true;
+}
+
+static void log_overriden_features(
+       struct adapter_service *as,
+       const char *feature_name,
+       enum adapter_feature_id id,
+       bool bool_feature,
+       uint32_t value)
+{
+       if (bool_feature)
+               dal_logger_write(as->ctx->logger,
+                       LOG_MAJOR_FEATURE_OVERRIDE,
+                       LOG_MINOR_FEATURE_OVERRIDE,
+                       "Overridden %s is %s now\n",
+                       feature_name,
+                       (value == 0) ? "disabled" : "enabled");
+       else
+               dal_logger_write(as->ctx->logger,
+                       LOG_MAJOR_FEATURE_OVERRIDE,
+                       LOG_MINOR_FEATURE_OVERRIDE,
+                       "Overridden %s new value: %d\n",
+                       feature_name,
+                       value);
+}
+
+/*************************************
+ * Local static functions definition *
+ *************************************/
+
+#define check_bool_feature(feature) \
+case FEATURE_ ## feature: \
+       if (param->bool_param_enable_mask & \
+               (1 << DAL_PARAM_ ## feature)) { \
+               *data = param->bool_param_values & \
+               (1 << DAL_PARAM_ ## feature); \
+               ret = true; \
+               feature_name = "FEATURE_" #feature; \
+       } \
+       break
+
+#define check_int_feature(feature) \
+case FEATURE_ ## feature: \
+       if (param->int_param_values[DAL_PARAM_ ## feature] != \
+               DAL_PARAM_INVALID_INT) { \
+               *data = param->int_param_values[DAL_PARAM_ ## feature];\
+               ret = true;\
+               bool_feature = false;\
+               feature_name = "FEATURE_" #feature;\
+       } \
+       break
+
+/*
+ * override_default_parameters
+ *
+ * Override features (from runtime parameter)
+ * corresponding to Adapter Service Feature ID
+ */
+static bool override_default_parameters(
+       struct adapter_service *as,
+       const struct dal_override_parameters *param,
+       const uint32_t idx,
+       uint32_t *data)
+{
+       bool ret = false;
+       bool bool_feature = true;
+       char *feature_name;
+
+       if (idx >= get_feature_entries_num()) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       switch (feature_entry_table[idx].feature_id) {
+       check_int_feature(MAX_COFUNC_NON_DP_DISPLAYS);
+       check_int_feature(DRR_SUPPORT);
+       check_bool_feature(LIGHT_SLEEP);
+       check_bool_feature(MAXIMIZE_STUTTER_MARKS);
+       check_bool_feature(MAXIMIZE_URGENCY_WATERMARKS);
+       check_bool_feature(USE_MAX_DISPLAY_CLK);
+       check_bool_feature(ENABLE_DFS_BYPASS);
+       check_bool_feature(POWER_GATING_PIPE_IN_TILE);
+       check_bool_feature(POWER_GATING_LB_PORTION);
+       check_bool_feature(PSR_ENABLE);
+       check_bool_feature(VARI_BRIGHT_ENABLE);
+       check_bool_feature(USE_PPLIB);
+       check_bool_feature(DISABLE_LPT_SUPPORT);
+       check_bool_feature(DUMMY_FBC_BACKEND);
+       check_bool_feature(ENABLE_GPU_SCALING);
+       default:
+               return false;
+       }
+       if (ret)
+               log_overriden_features(
+                       as,
+                       feature_name,
+                       feature_entry_table[idx].feature_id,
+                       bool_feature,
+                       *data);
+
+       return ret;
+}
+
+/*
+ * get_feature_value_from_data_sources
+ *
+ * For a given feature, determine its value from ASIC cap and wireless
+ * data source.
+ * idx : index of feature_entry_table for the feature id.
+ */
+static bool get_feature_value_from_data_sources(
+               const struct adapter_service *as,
+               const uint32_t idx,
+               uint32_t *data)
+{
+       if (idx >= get_feature_entries_num()) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       switch (feature_entry_table[idx].feature_id) {
+       case FEATURE_MAX_COFUNC_NON_DP_DISPLAYS:
+               *data = as->asic_cap->data[ASIC_DATA_MAX_COFUNC_NONDP_DISPLAYS];
+               break;
+
+       case FEATURE_WIRELESS_LIMIT_720P:
+               *data = as->asic_cap->caps.WIRELESS_LIMIT_TO_720P;
+               break;
+
+       case FEATURE_WIRELESS_FULL_TIMING_ADJUSTMENT:
+               *data = as->asic_cap->caps.WIRELESS_FULL_TIMING_ADJUSTMENT;
+               break;
+
+       case FEATURE_MODIFY_TIMINGS_FOR_WIRELESS:
+               *data = as->asic_cap->caps.WIRELESS_TIMING_ADJUSTMENT;
+               break;
+
+       case FEATURE_SUPPORTED_HDMI_CONNECTION_NUM:
+               *data =
+               as->asic_cap->data[ASIC_DATA_SUPPORTED_HDMI_CONNECTION_NUM];
+               break;
+
+       case FEATURE_DETECT_REQUIRE_HPD_HIGH:
+               *data = as->asic_cap->caps.HPD_CHECK_FOR_EDID;
+               break;
+
+       case FEATURE_NO_HPD_LOW_POLLING_VCC_OFF:
+               *data = as->asic_cap->caps.NO_VCC_OFF_HPD_POLLING;
+               break;
+
+       case FEATURE_STUTTER_MODE:
+               *data = as->asic_cap->data[ASIC_DATA_STUTTERMODE];
+               break;
+
+       case FEATURE_WIRELESS_ENABLE:
+               *data = as->wireless_data.wireless_enable;
+               break;
+
+       case FEATURE_8BPP_SUPPORTED:
+               *data = as->asic_cap->caps.SUPPORT_8BPP;
+               break;
+
+       default:
+               return false;
+       }
+
+       return true;
+}
+
+/* get_bool_value
+ *
+ * Get the boolean value of a given feature
+ */
+static bool get_bool_value(
+       const uint32_t set,
+       const uint32_t idx)
+{
+       if (idx >= 32) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       return ((set & (1 << idx)) != 0);
+}
+
+/*
+ * get_hpd_info
+ *
+ * Get HPD information from BIOS
+ */
+static bool get_hpd_info(struct adapter_service *as,
+       struct graphics_object_id id,
+       struct graphics_object_hpd_info *info)
+{
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       return BP_RESULT_OK == dcb->funcs->get_hpd_info(dcb, id, info);
+}
+
+/*
+ * lookup_feature_entry
+ *
+ * Find the entry index of a given feature in feature table
+ */
+static uint32_t lookup_feature_entry(
+       enum adapter_feature_id feature_id)
+{
+       uint32_t entries_num = get_feature_entries_num();
+       uint32_t i = 0;
+
+       while (i != entries_num) {
+               if (feature_entry_table[i].feature_id == feature_id)
+                       break;
+
+               ++i;
+       }
+
+       return i;
+}
+
+/*
+ * set_bool_value
+ *
+ * Set the boolean value of a given feature
+ */
+static void set_bool_value(
+       uint32_t *set,
+       const uint32_t idx,
+       bool value)
+{
+       if (idx >= 32) {
+               ASSERT_CRITICAL(false);
+               return;
+       }
+
+       if (value)
+               *set |= (1 << idx);
+       else
+               *set &= ~(1 << idx);
+}
+
+/*
+ * generate_feature_set
+ *
+ * Generate the internal feature set from multiple data sources
+ */
+static bool generate_feature_set(
+               struct adapter_service *as,
+               const struct dal_override_parameters *param)
+{
+       uint32_t i = 0;
+       uint32_t value = 0;
+       uint32_t set_idx = 0;
+       uint32_t internal_idx = 0;
+       uint32_t entry_num = 0;
+       const struct feature_source_entry *entry = NULL;
+
+       dm_memset(adapter_feature_set, 0, sizeof(adapter_feature_set));
+       entry_num = get_feature_entries_num();
+
+
+       while (i != entry_num) {
+               entry = &feature_entry_table[i];
+
+               if (entry->feature_id <= FEATURE_UNKNOWN ||
+                               entry->feature_id >= FEATURE_MAXIMUM) {
+                       ASSERT_CRITICAL(false);
+                       return false;
+               }
+
+               set_idx = (uint32_t)((entry->feature_id - 1) / 32);
+               internal_idx = (uint32_t)((entry->feature_id - 1) % 32);
+
+               /* TODO: wireless, runtime parameter, vbios */
+               if (!override_default_parameters(as, param, i, &value)) {
+                       if (!get_feature_value_from_data_sources(
+                                       as, i, &value)) {
+                               /*
+                                * Can't find feature values from
+                                * above data sources
+                                * Assign default value
+                                */
+                               value = entry->default_value;
+                       }
+               }
+
+               if (entry->is_boolean_type)
+                       set_bool_value(&adapter_feature_set[set_idx],
+                                       internal_idx,
+                                       value != 0);
+               else
+                       adapter_feature_set[set_idx] = value;
+
+               i++;
+       }
+
+       return true;
+}
+
+
+/*
+ * create_hw_ctx
+ *
+ * Create HW context for adapter service. This is DCE specific.
+ */
+static struct hw_ctx_adapter_service *create_hw_ctx(
+       enum dce_version dce_version,
+       enum dce_environment dce_environment,
+       struct dc_context *ctx)
+{
+       if (IS_FPGA_MAXIMUS_DC(dce_environment))
+               return dal_adapter_service_create_hw_ctx_diag(ctx);
+
+       switch (dce_version) {
+#if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
+       case DCE_VERSION_10_0:
+               return dal_adapter_service_create_hw_ctx_dce110(ctx);
+#endif
+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
+       case DCE_VERSION_11_0:
+               return dal_adapter_service_create_hw_ctx_dce110(ctx);
+#endif
+       default:
+               ASSERT_CRITICAL(false);
+               return NULL;
+       }
+}
+
+/*
+ * adapter_service_destruct
+ *
+ * Release memory of objects in adapter service
+ */
+static void adapter_service_destruct(
+       struct adapter_service *as)
+{
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       dal_adapter_service_destroy_hw_ctx(&as->hw_ctx);
+       dal_i2caux_destroy(&as->i2caux);
+       dal_gpio_service_destroy(&as->gpio_service);
+       dal_asic_capability_destroy(&as->asic_cap);
+
+       dcb->funcs->destroy_integrated_info(dcb, &as->integrated_info);
+
+       if (as->dcb_internal) {
+               /* We are responsible only for destruction of Internal BIOS.
+                * The External one will be destroyed by its creator. */
+               dal_bios_parser_destroy(&as->dcb_internal);
+       }
+}
+
+/*
+ * adapter_service_construct
+ *
+ * Construct the derived type of adapter service
+ */
+static bool adapter_service_construct(
+       struct adapter_service *as,
+       struct as_init_data *init_data)
+{
+       struct dc_bios *dcb;
+       enum dce_version dce_version;
+
+       if (!init_data)
+               return false;
+
+       /* Create ASIC capability */
+       as->ctx = init_data->ctx;
+       as->asic_cap = dal_asic_capability_create(
+                       &init_data->hw_init_data, as->ctx);
+
+       if (!as->asic_cap) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
+       if (dal_adapter_service_get_dce_version(as) == DCE_VERSION_11_0) {
+               uint32_t i;
+
+               for (i = 0; i < ARRAY_SIZE(feature_entry_table); i++) {
+                       enum adapter_feature_id id =
+                               feature_entry_table[i].feature_id;
+                       if (id == FEATURE_MAXIMIZE_URGENCY_WATERMARKS ||
+                               id == FEATURE_MAXIMIZE_STUTTER_MARKS ||
+                               id == FEATURE_MAXIMIZE_NBP_MARKS)
+                               feature_entry_table[i].default_value = true;
+               }
+       }
+#endif
+
+       /* Generate feature set table */
+       if (!generate_feature_set(as, init_data->display_param)) {
+               ASSERT_CRITICAL(false);
+               goto failed_to_generate_features;
+       }
+
+       as->dce_environment = init_data->dce_environment;
+
+       if (init_data->vbios_override)
+               as->dcb_override = init_data->vbios_override;
+       else {
+               /* Create BIOS parser */
+               init_data->bp_init_data.ctx = init_data->ctx;
+
+               as->dcb_internal = dal_bios_parser_create(
+                               &init_data->bp_init_data, as);
+
+               if (!as->dcb_internal) {
+                       ASSERT_CRITICAL(false);
+                       goto failed_to_create_bios_parser;
+               }
+       }
+
+       dcb = dal_adapter_service_get_bios_parser(as);
+
+       dce_version = dal_adapter_service_get_dce_version(as);
+
+       /* Create GPIO service */
+       as->gpio_service = dal_gpio_service_create(
+                       dce_version,
+                       as->dce_environment,
+                       as->ctx);
+
+       if (!as->gpio_service) {
+               ASSERT_CRITICAL(false);
+               goto failed_to_create_gpio_service;
+       }
+
+       /* Create I2C AUX */
+       as->i2caux = dal_i2caux_create(as, as->ctx);
+
+       if (!as->i2caux) {
+               ASSERT_CRITICAL(false);
+               goto failed_to_create_i2caux;
+       }
+
+       /* Create Adapter Service HW Context*/
+       as->hw_ctx = create_hw_ctx(
+                       dce_version,
+                       as->dce_environment,
+                       as->ctx);
+
+       if (!as->hw_ctx) {
+               ASSERT_CRITICAL(false);
+               goto failed_to_create_hw_ctx;
+       }
+
+       /* Avoid wireless encoder creation in upstream branch. */
+
+       /* Integrated info is not provided on discrete ASIC. NULL is allowed */
+       as->integrated_info = dcb->funcs->create_integrated_info(dcb);
+
+       dcb->funcs->post_init(dcb);
+
+       /* Generate backlight translation table and initializes
+                         other brightness properties */
+       as->backlight_caps_initialized = false;
+
+       get_platform_info_methods(as);
+
+       initialize_backlight_caps(as);
+
+       return true;
+
+failed_to_generate_features:
+       dal_adapter_service_destroy_hw_ctx(&as->hw_ctx);
+
+failed_to_create_hw_ctx:
+       dal_i2caux_destroy(&as->i2caux);
+
+failed_to_create_i2caux:
+       dal_gpio_service_destroy(&as->gpio_service);
+
+failed_to_create_gpio_service:
+       if (as->dcb_internal)
+               dal_bios_parser_destroy(&as->dcb_internal);
+
+failed_to_create_bios_parser:
+       dal_asic_capability_destroy(&as->asic_cap);
+
+       return false;
+}
+
+/*
+ * Global function definition
+ */
+
+/*
+ * dal_adapter_service_create
+ *
+ * Create adapter service
+ */
+struct adapter_service *dal_adapter_service_create(
+       struct as_init_data *init_data)
+{
+       struct adapter_service *as;
+
+       as = dm_alloc(init_data->ctx, sizeof(struct adapter_service));
+
+       if (!as) {
+               ASSERT_CRITICAL(false);
+               return NULL;
+       }
+
+       if (adapter_service_construct(as, init_data))
+               return as;
+
+       ASSERT_CRITICAL(false);
+
+       dm_free(init_data->ctx, as);
+
+       return NULL;
+}
+
+/*
+ * dal_adapter_service_destroy
+ *
+ * Destroy adapter service and objects it contains
+ */
+void dal_adapter_service_destroy(
+       struct adapter_service **as)
+{
+       if (!as) {
+               ASSERT_CRITICAL(false);
+               return;
+       }
+
+       if (!*as) {
+               ASSERT_CRITICAL(false);
+               return;
+       }
+
+       adapter_service_destruct(*as);
+
+       dm_free((*as)->ctx, *as);
+
+       *as = NULL;
+}
+
+/*
+ * dal_adapter_service_get_dce_version
+ *
+ * Get the DCE version of current ASIC
+ */
+enum dce_version dal_adapter_service_get_dce_version(
+       const struct adapter_service *as)
+{
+       uint32_t version = as->asic_cap->data[ASIC_DATA_DCE_VERSION];
+
+       switch (version) {
+#if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
+       case 0x100:
+               return DCE_VERSION_10_0;
+#endif
+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
+       case 0x110:
+               return DCE_VERSION_11_0;
+#endif
+       default:
+               ASSERT_CRITICAL(false);
+               return DCE_VERSION_UNKNOWN;
+       }
+}
+
+enum dce_environment dal_adapter_service_get_dce_environment(
+       const struct adapter_service *as)
+{
+       return as->dce_environment;
+}
+
+
+/*
+ * dal_adapter_service_get_controllers_num
+ *
+ * Get number of controllers
+ */
+uint8_t dal_adapter_service_get_controllers_num(
+       struct adapter_service *as)
+{
+       uint32_t result = as->asic_cap->data[ASIC_DATA_CONTROLLERS_NUM];
+
+       /* Check the "max num of controllers" feature,
+        * use it for debugging purposes only */
+       /* TODO implement
+        * dal_adapter_service_get_feature_value(as, ) */
+
+       return result;
+}
+
+/** Get total number of connectors.
+ *
+ * \param as   Adapter Service
+ *
+ * \return Total number of connectors. It is up-to-the caller to decide
+ *     if the number is valid.
+ */
+uint8_t dal_adapter_service_get_connectors_num(
+       struct adapter_service *as)
+{
+       uint8_t vbios_connectors_num = 0;
+       uint8_t wireless_connectors_num = 0;
+       struct dc_bios *dcb;
+
+       dcb = dal_adapter_service_get_bios_parser(as);
+
+       vbios_connectors_num = dcb->funcs->get_connectors_number(dcb);
+
+       wireless_connectors_num = wireless_get_connectors_num(as);
+
+       return vbios_connectors_num + wireless_connectors_num;
+}
+
+static bool is_wireless_object(struct graphics_object_id id)
+{
+       if ((id.type == OBJECT_TYPE_ENCODER &&
+               id.id == ENCODER_ID_INTERNAL_WIRELESS) ||
+               (id.type == OBJECT_TYPE_CONNECTOR && id.id ==
+                       CONNECTOR_ID_WIRELESS) ||
+               (id.type == OBJECT_TYPE_CONNECTOR && id.id ==
+                       CONNECTOR_ID_MIRACAST))
+               return true;
+       return false;
+}
+
+/**
+ * Get the number of source objects of an object
+ *
+ * \param [in] as: Adapter Service
+ *
+ * \param [in] id: The graphics object id
+ *
+ * \return
+ *     The number of the source objects of an object
+ */
+uint32_t dal_adapter_service_get_src_num(
+       struct adapter_service *as, struct graphics_object_id id)
+{
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       if (is_wireless_object(id))
+               return wireless_get_srcs_num(as, id);
+       else
+               return dcb->funcs->get_src_number(dcb, id);
+}
+
+/**
+ * Get the source objects of an object
+ *
+ * \param [in] id      The graphics object id
+ * \param [in] index   Enumerating index which starts at 0
+ *
+ * \return If enumerating successfully, return the VALID source object id,
+ *     otherwise, returns "zeroed out" object id.
+ *     Client should call dal_graphics_object_id_is_valid() to check
+ *     weather the id is valid.
+ */
+struct graphics_object_id dal_adapter_service_get_src_obj(
+       struct adapter_service *as,
+       struct graphics_object_id id,
+       uint32_t index)
+{
+       struct graphics_object_id src_object_id;
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       if (is_wireless_object(id))
+               src_object_id = wireless_get_src_obj_id(as, id, index);
+       else {
+               if (BP_RESULT_OK != dcb->funcs->get_src_obj(dcb, id, index,
+                               &src_object_id)) {
+                       src_object_id =
+                               dal_graphics_object_id_init(
+                                       0,
+                                       ENUM_ID_UNKNOWN,
+                                       OBJECT_TYPE_UNKNOWN);
+               }
+       }
+
+       return src_object_id;
+}
+
+/** Get connector object id associated with a connector index.
+ *
+ * \param as   Adapter Service
+ *
+ * \param connector_index Index of connector between zero and total number
+ *     returned by dal_adapter_service_get_connectors_num()
+ *
+ * \return graphics object id corresponding to the connector_index.
+ */
+struct graphics_object_id dal_adapter_service_get_connector_obj_id(
+               struct adapter_service *as,
+               uint8_t connector_index)
+{
+       struct dc_bios *dcb;
+       uint8_t bios_connectors_num;
+
+       dcb = dal_adapter_service_get_bios_parser(as);
+
+       bios_connectors_num = dcb->funcs->get_connectors_number(dcb);
+
+       if (connector_index >= bios_connectors_num)
+               return wireless_get_connector_id(as, connector_index);
+       else
+               return dcb->funcs->get_connector_id(dcb, connector_index);
+}
+
+bool dal_adapter_service_get_device_tag(
+               struct adapter_service *as,
+               struct graphics_object_id connector_object_id,
+               uint32_t device_tag_index,
+               struct connector_device_tag_info *info)
+{
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       if (BP_RESULT_OK == dcb->funcs->get_device_tag(dcb,
+                       connector_object_id, device_tag_index, info))
+               return true;
+       else
+               return false;
+}
+
+/* Check if DeviceId is supported by ATOM_OBJECT_HEADER support info */
+bool dal_adapter_service_is_device_id_supported(struct adapter_service *as,
+               struct device_id id)
+{
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       return dcb->funcs->is_device_id_supported(dcb, id);
+}
+
+bool dal_adapter_service_is_meet_underscan_req(struct adapter_service *as)
+{
+       struct firmware_info fw_info;
+       enum bp_result bp_result = dal_adapter_service_get_firmware_info(
+               as, &fw_info);
+       uint32_t disp_clk_limit =
+               as->asic_cap->data[ASIC_DATA_MIN_DISPCLK_FOR_UNDERSCAN];
+       if (BP_RESULT_OK == bp_result) {
+               dal_logger_write(as->ctx->logger,
+                       LOG_MAJOR_ERROR,
+                       LOG_MINOR_COMPONENT_ADAPTER_SERVICE,
+                       "Read firmware is NULL");
+               return false;
+       }
+       if (fw_info.default_display_engine_pll_frequency < disp_clk_limit)
+               return false;
+       return true;
+}
+
+bool dal_adapter_service_underscan_for_hdmi_only(struct adapter_service *as)
+{
+       return as->asic_cap->caps.UNDERSCAN_FOR_HDMI_ONLY;
+}
+/*
+ * dal_adapter_service_get_clock_sources_num
+ *
+ * Get number of clock sources
+ */
+uint8_t dal_adapter_service_get_clock_sources_num(
+       struct adapter_service *as)
+{
+       struct firmware_info fw_info;
+       uint32_t max_clk_src = 0;
+       uint32_t num = as->asic_cap->data[ASIC_DATA_CLOCKSOURCES_NUM];
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       /*
+        * Check is system supports the use of the External clock source
+        * as a clock source for DP
+        */
+       enum bp_result bp_result = dcb->funcs->get_firmware_info(dcb, &fw_info);
+
+       if (BP_RESULT_OK == bp_result &&
+                       fw_info.external_clock_source_frequency_for_dp != 0)
+               ++num;
+
+       /*
+        * Add clock source for wireless if supported
+        */
+       num += (uint32_t)wireless_get_clocks_num(as);
+
+       /* Check the "max number of clock sources" feature */
+       if (dal_adapter_service_get_feature_value(
+                       FEATURE_MAX_CLOCK_SOURCE_NUM,
+                       &max_clk_src,
+                       sizeof(uint32_t)))
+               if ((max_clk_src != 0) && (max_clk_src < num))
+                       num = max_clk_src;
+
+       return num;
+}
+
+/*
+ * dal_adapter_service_get_func_controllers_num
+ *
+ * Get number of controllers
+ */
+uint8_t dal_adapter_service_get_func_controllers_num(
+       struct adapter_service *as)
+{
+       uint32_t result =
+               as->asic_cap->data[ASIC_DATA_FUNCTIONAL_CONTROLLERS_NUM];
+
+       /* Check the "max num of controllers" feature,
+        * use it for debugging purposes only */
+
+       /* Limit number of controllers by OS */
+
+       struct asic_feature_flags flags;
+
+       flags.raw = as->asic_cap->data[ASIC_DATA_FEATURE_FLAGS];
+
+       if (flags.bits.LEGACY_CLIENT &&
+               (result > LEGACY_MAX_NUM_OF_CONTROLLERS))
+               result = LEGACY_MAX_NUM_OF_CONTROLLERS;
+
+       return result;
+}
+
+/*
+ * dal_adapter_service_is_feature_supported
+ *
+ * Return if a given feature is supported by the ASIC. The feature has to be
+ * a boolean type.
+ */
+bool dal_adapter_service_is_feature_supported(
+       enum adapter_feature_id feature_id)
+{
+       bool data = 0;
+
+       dal_adapter_service_get_feature_value(feature_id, &data, sizeof(bool));
+
+       return data;
+}
+
+/**
+ * Reports maximum number of confunctional non-DP displays.
+ * Value can be overriden if FEATURE_REPORT_SINGLE_SELECTED_TIMING feature is
+ * enabled.
+ *
+ * \return
+ *     Maximum number of confunctional non-DP displays
+ */
+uint32_t dal_adapter_service_get_max_cofunc_non_dp_displays(void)
+{
+       uint32_t non_dp_displays = DEFAULT_NUM_COFUNC_NON_DP_DISPLAYS;
+
+       if (true == dal_adapter_service_get_feature_value(
+                       FEATURE_MAX_COFUNC_NON_DP_DISPLAYS,
+                       &non_dp_displays,
+                       sizeof(non_dp_displays))) {
+               /* the cached value exist */
+               /* TODO: add more logic as per-DAL2 */
+       }
+
+       return non_dp_displays;
+}
+
+uint32_t dal_adapter_service_get_single_selected_timing_signals(void)
+{
+       uint32_t signals_bitmap = 0;
+
+       if (dal_adapter_service_is_feature_supported(
+                       FEATURE_REPORT_SINGLE_SELECTED_TIMING)) {
+               /* the cached value exist */
+               /* TODO: add more logic as per-DAL2 */
+               signals_bitmap = 0;
+       }
+
+       return signals_bitmap;
+}
+
+/*
+ * dal_adapter_service_get_i2c_info
+ *
+ * Get I2C information from BIOS
+ */
+bool dal_adapter_service_get_i2c_info(
+       struct adapter_service *as,
+       struct graphics_object_id id,
+       struct graphics_object_i2c_info *i2c_info)
+{
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       if (!i2c_info) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       return BP_RESULT_OK == dcb->funcs->get_i2c_info(dcb, id, i2c_info);
+}
+
+/*
+ * dal_adapter_service_obtain_ddc
+ *
+ * Obtain DDC
+ */
+struct ddc *dal_adapter_service_obtain_ddc(
+       struct adapter_service *as,
+       struct graphics_object_id id)
+{
+       struct graphics_object_i2c_info i2c_info;
+       struct gpio_ddc_hw_info hw_info;
+
+
+       if (!dal_adapter_service_get_i2c_info(as, id, &i2c_info))
+               return NULL;
+
+       hw_info.ddc_channel = i2c_info.i2c_line;
+       hw_info.hw_supported = i2c_info.i2c_hw_assist;
+
+       return dal_gpio_service_create_ddc(
+               as->gpio_service,
+               i2c_info.gpio_info.clk_a_register_index,
+               1 << i2c_info.gpio_info.clk_a_shift,
+               &hw_info);
+}
+
+/*
+ * dal_adapter_service_release_ddc
+ *
+ * Release DDC
+ */
+void dal_adapter_service_release_ddc(
+       struct adapter_service *as,
+       struct ddc *ddc)
+{
+       dal_gpio_service_destroy_ddc(&ddc);
+}
+
+/*
+ * dal_adapter_service_obtain_hpd_irq
+ *
+ * Obtain HPD interrupt request
+ */
+struct irq *dal_adapter_service_obtain_hpd_irq(
+       struct adapter_service *as,
+       struct graphics_object_id id)
+{
+       enum bp_result bp_result;
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+       struct graphics_object_hpd_info hpd_info;
+       struct gpio_pin_info pin_info;
+
+       if (!get_hpd_info(as, id, &hpd_info))
+               return NULL;
+
+       bp_result = dcb->funcs->get_gpio_pin_info(dcb,
+               hpd_info.hpd_int_gpio_uid, &pin_info);
+
+       if (bp_result != BP_RESULT_OK) {
+               ASSERT(bp_result == BP_RESULT_NORECORD);
+               return NULL;
+       }
+
+       return dal_gpio_service_create_irq(
+               as->gpio_service,
+               pin_info.offset,
+               pin_info.mask);
+}
+
+/*
+ * dal_adapter_service_release_irq
+ *
+ * Release interrupt request
+ */
+void dal_adapter_service_release_irq(
+       struct adapter_service *as,
+       struct irq *irq)
+{
+       dal_gpio_service_destroy_irq(&irq);
+}
+
+/*
+ * dal_adapter_service_get_ss_info_num
+ *
+ * Get number of spread spectrum entries from BIOS
+ */
+uint32_t dal_adapter_service_get_ss_info_num(
+       struct adapter_service *as,
+       enum as_signal_type signal)
+{
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       return dcb->funcs->get_ss_entry_number(dcb, signal);
+}
+
+/*
+ * dal_adapter_service_get_ss_info
+ *
+ * Get spread spectrum info from BIOS
+ */
+bool dal_adapter_service_get_ss_info(
+       struct adapter_service *as,
+       enum as_signal_type signal,
+       uint32_t idx,
+       struct spread_spectrum_info *info)
+{
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       enum bp_result bp_result = dcb->funcs->get_spread_spectrum_info(dcb,
+                       signal, idx, info);
+
+       return BP_RESULT_OK == bp_result;
+}
+
+/*
+ * dal_adapter_service_get_integrated_info
+ *
+ * Get integrated information on BIOS
+ */
+bool dal_adapter_service_get_integrated_info(
+       struct adapter_service *as,
+       struct integrated_info *info)
+{
+       if (info == NULL || as->integrated_info == NULL)
+               return false;
+
+       dm_memmove(info, as->integrated_info, sizeof(struct integrated_info));
+
+       return true;
+}
+
+/*
+ * dal_adapter_service_is_dfs_bypass_enabled
+ *
+ * Check if DFS bypass is enabled
+ */
+bool dal_adapter_service_is_dfs_bypass_enabled(
+       struct adapter_service *as)
+{
+       if (as->integrated_info == NULL)
+               return false;
+       if ((as->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) &&
+               dal_adapter_service_is_feature_supported(
+                       FEATURE_ENABLE_DFS_BYPASS))
+               return true;
+       else
+               return false;
+}
+
+/*
+ * dal_adapter_service_get_sw_i2c_speed
+ *
+ * Get SW I2C speed
+ */
+uint32_t dal_adapter_service_get_sw_i2c_speed(
+       struct adapter_service *as)
+{
+       /* TODO: only from ASIC caps. Feature key is not implemented*/
+       return as->asic_cap->data[ASIC_DATA_DEFAULT_I2C_SPEED_IN_KHZ];
+}
+
+/*
+ * dal_adapter_service_get_hw_i2c_speed
+ *
+ * Get HW I2C speed
+ */
+uint32_t dal_adapter_service_get_hw_i2c_speed(
+       struct adapter_service *as)
+{
+       /* TODO: only from ASIC caps. Feature key is not implemented*/
+       return as->asic_cap->data[ASIC_DATA_DEFAULT_I2C_SPEED_IN_KHZ];
+}
+
+/*
+ * dal_adapter_service_get_mc_latency
+ *
+ * Get memory controller latency
+ */
+uint32_t dal_adapter_service_get_mc_latency(
+       struct adapter_service *as)
+{
+       return as->asic_cap->data[ASIC_DATA_MC_LATENCY];
+}
+
+/*
+ * dal_adapter_service_get_asic_vram_bit_width
+ *
+ * Get the video RAM bit width set on the ASIC
+ */
+uint32_t dal_adapter_service_get_asic_vram_bit_width(
+       struct adapter_service *as)
+{
+       return as->asic_cap->data[ASIC_DATA_VRAM_BITWIDTH];
+}
+
+/*
+ * dal_adapter_service_get_asic_bugs
+ *
+ * Get the bug flags set on this ASIC
+ */
+struct asic_bugs dal_adapter_service_get_asic_bugs(
+       struct adapter_service *as)
+{
+       return as->asic_cap->bugs;
+}
+
+
+struct dal_asic_runtime_flags dal_adapter_service_get_asic_runtime_flags(
+               struct adapter_service *as)
+{
+       return as->asic_cap->runtime_flags;
+}
+
+/*
+ * dal_adapter_service_get_line_buffer_size
+ *
+ * Get line buffer size
+ */
+uint32_t dal_adapter_service_get_line_buffer_size(
+       struct adapter_service *as)
+{
+       return as->asic_cap->data[ASIC_DATA_LINEBUFFER_SIZE];
+}
+
+/*
+ * dal_adapter_service_get_bandwidth_tuning_params
+ *
+ * Get parameters for bandwidth tuning
+ */
+bool dal_adapter_service_get_bandwidth_tuning_params(
+       struct adapter_service *as,
+       union bandwidth_tuning_params *params)
+{
+       /* TODO: add implementation */
+       /* note: data comes from runtime parameters */
+       return false;
+}
+
+/*
+ * dal_adapter_service_get_feature_flags
+ *
+ * Get a copy of ASIC feature flags
+ */
+struct asic_feature_flags dal_adapter_service_get_feature_flags(
+       struct adapter_service *as)
+{
+       struct asic_feature_flags result = { { 0 } };
+
+       if (!as) {
+               ASSERT_CRITICAL(false);
+               return result;
+       }
+
+       result.raw = as->asic_cap->data[ASIC_DATA_FEATURE_FLAGS];
+
+       return result;
+}
+
+/*
+ * dal_adapter_service_get_dram_bandwidth_efficiency
+ *
+ * Get efficiency of DRAM
+ */
+uint32_t dal_adapter_service_get_dram_bandwidth_efficiency(
+       struct adapter_service *as)
+{
+       return as->asic_cap->data[ASIC_DATA_DRAM_BANDWIDTH_EFFICIENCY];
+}
+
+/*
+ * dal_adapter_service_obtain_gpio
+ *
+ * Obtain GPIO
+ */
+struct gpio *dal_adapter_service_obtain_gpio(
+       struct adapter_service *as,
+       enum gpio_id id,
+       uint32_t en)
+{
+       return dal_gpio_service_create_gpio_ex(
+               as->gpio_service, id, en,
+               GPIO_PIN_OUTPUT_STATE_DEFAULT);
+}
+
+/*
+ * dal_adapter_service_obtain_stereo_gpio
+ *
+ * Obtain GPIO for stereo3D
+ */
+struct gpio *dal_adapter_service_obtain_stereo_gpio(
+       struct adapter_service *as)
+{
+       const bool have_param_stereo_gpio = false;
+
+       struct asic_feature_flags result;
+
+       result.raw = as->asic_cap->data[ASIC_DATA_FEATURE_FLAGS];
+
+       /* Case 1 : Workstation stereo */
+       if (result.bits.WORKSTATION_STEREO) {
+               /* "active low" <--> "default 3d right eye polarity" = false */
+               return dal_gpio_service_create_gpio_ex(as->gpio_service,
+                               GPIO_ID_GENERIC, GPIO_GENERIC_A,
+                               GPIO_PIN_OUTPUT_STATE_ACTIVE_LOW);
+       /* Case 2 : runtime parameter override for sideband stereo */
+       } else if (have_param_stereo_gpio) {
+               /* TODO implement */
+               return NULL;
+               /* Case 3 : VBIOS gives us GPIO for sideband stereo */
+       } else {
+               const struct graphics_object_id id =
+                               dal_graphics_object_id_init(GENERIC_ID_STEREO,
+                                               ENUM_ID_1, OBJECT_TYPE_GENERIC);
+
+               struct bp_gpio_cntl_info cntl_info;
+               struct gpio_pin_info pin_info;
+               struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+               /* Get GPIO record for this object.
+                * Stereo GPIO record should have exactly one entry
+                * where active state defines stereosync polarity */
+               if (1 != dcb->funcs->get_gpio_record(
+                                               dcb, id, &cntl_info,
+                                               1)) {
+                       return NULL;
+               } else if (BP_RESULT_OK
+                               != dcb->funcs->get_gpio_pin_info(
+                                               dcb, cntl_info.id,
+                                               &pin_info)) {
+                       /*ASSERT_CRITICAL(false);*/
+                       return NULL;
+               } else {
+                       return dal_gpio_service_create_gpio_ex(as->gpio_service,
+                                       pin_info.offset, pin_info.mask,
+                                       cntl_info.state);
+               }
+       }
+}
+
+/*
+ * dal_adapter_service_release_gpio
+ *
+ * Release GPIO
+ */
+void dal_adapter_service_release_gpio(
+       struct adapter_service *as,
+       struct gpio *gpio)
+{
+       dal_gpio_service_destroy_gpio(&gpio);
+}
+
+/*
+ * dal_adapter_service_get_firmware_info
+ *
+ * Get firmware information from BIOS
+ */
+bool dal_adapter_service_get_firmware_info(
+       struct adapter_service *as,
+       struct firmware_info *info)
+{
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       return dcb->funcs->get_firmware_info(dcb, info) == BP_RESULT_OK;
+}
+
+/*
+ * dal_adapter_service_get_audio_support
+ *
+ * Get information on audio support
+ */
+union audio_support dal_adapter_service_get_audio_support(
+       struct adapter_service *as)
+{
+       return dal_adapter_service_hw_ctx_get_audio_support(as->hw_ctx);
+}
+
+/*
+ * dal_adapter_service_get_stream_engines_num
+ *
+ * Get number of stream engines
+ */
+uint8_t dal_adapter_service_get_stream_engines_num(
+       struct adapter_service *as)
+{
+       return as->asic_cap->data[ASIC_DATA_DIGFE_NUM];
+}
+
+/*
+ * dal_adapter_service_get_feature_value
+ *
+ * Get the cached value of a given feature. This value can be a boolean, int,
+ * or characters.
+ */
+bool dal_adapter_service_get_feature_value(
+       const enum adapter_feature_id feature_id,
+       void *data,
+       uint32_t size)
+{
+       uint32_t entry_idx = 0;
+       uint32_t set_idx = 0;
+       uint32_t set_internal_idx = 0;
+
+       if (feature_id >= FEATURE_MAXIMUM || feature_id <= FEATURE_UNKNOWN) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       if (data == NULL) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       entry_idx = lookup_feature_entry(feature_id);
+       set_idx = (uint32_t)((feature_id - 1)/32);
+       set_internal_idx = (uint32_t)((feature_id - 1) % 32);
+
+       if (entry_idx >= get_feature_entries_num()) {
+               /* Cannot find this entry */
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       if (feature_entry_table[entry_idx].is_boolean_type) {
+               if (size != sizeof(bool)) {
+                       ASSERT_CRITICAL(false);
+                       return false;
+               }
+
+               *(bool *)data = get_bool_value(adapter_feature_set[set_idx],
+                               set_internal_idx);
+       } else {
+               if (size != sizeof(uint32_t)) {
+                       ASSERT_CRITICAL(false);
+                       return false;
+               }
+
+               *(uint32_t *)data = adapter_feature_set[set_idx];
+       }
+
+       return true;
+}
+
+/*
+ * dal_adapter_service_get_memory_type_multiplier
+ *
+ * Get multiplier for the memory type
+ */
+uint32_t dal_adapter_service_get_memory_type_multiplier(
+       struct adapter_service *as)
+{
+       return as->asic_cap->data[ASIC_DATA_MEMORYTYPE_MULTIPLIER];
+}
+
+/*
+ * dal_adapter_service_get_bios_parser
+ *
+ * Get BIOS parser handler
+ */
+struct dc_bios *dal_adapter_service_get_bios_parser(
+       struct adapter_service *as)
+{
+       return as->dcb_override ? as->dcb_override : as->dcb_internal;
+}
+
+/*
+ * dal_adapter_service_get_i2caux
+ *
+ * Get i2c aux handler
+ */
+struct i2caux *dal_adapter_service_get_i2caux(
+       struct adapter_service *as)
+{
+       return as->i2caux;
+}
+
+bool dal_adapter_service_initialize_hw_data(
+       struct adapter_service *as)
+{
+       return as->hw_ctx->funcs->power_up(as->hw_ctx);
+}
+
+struct graphics_object_id dal_adapter_service_enum_fake_path_resource(
+       struct adapter_service *as,
+       uint32_t index)
+{
+       return as->hw_ctx->funcs->enum_fake_path_resource(as->hw_ctx, index);
+}
+
+struct graphics_object_id dal_adapter_service_enum_stereo_sync_object(
+       struct adapter_service *as,
+       uint32_t index)
+{
+       return as->hw_ctx->funcs->enum_stereo_sync_object(as->hw_ctx, index);
+}
+
+struct graphics_object_id dal_adapter_service_enum_sync_output_object(
+       struct adapter_service *as,
+       uint32_t index)
+{
+       return as->hw_ctx->funcs->enum_sync_output_object(as->hw_ctx, index);
+}
+
+struct graphics_object_id dal_adapter_service_enum_audio_object(
+       struct adapter_service *as,
+       uint32_t index)
+{
+       return as->hw_ctx->funcs->enum_audio_object(as->hw_ctx, index);
+}
+
+
+void dal_adapter_service_update_audio_connectivity(
+       struct adapter_service *as,
+       uint32_t number_of_audio_capable_display_path)
+{
+       as->hw_ctx->funcs->update_audio_connectivity(
+               as->hw_ctx,
+               number_of_audio_capable_display_path,
+               dal_adapter_service_get_controllers_num(as));
+}
+
+bool dal_adapter_service_has_embedded_display_connector(
+       struct adapter_service *as)
+{
+       uint8_t index;
+       uint8_t num_connectors = dal_adapter_service_get_connectors_num(as);
+
+       if (num_connectors == 0 || num_connectors > ENUM_ID_COUNT)
+               return false;
+
+       for (index = 0; index < num_connectors; index++) {
+               struct graphics_object_id obj_id =
+                       dal_adapter_service_get_connector_obj_id(as, index);
+               enum connector_id connector_id =
+                       dal_graphics_object_id_get_connector_id(obj_id);
+
+               if ((connector_id == CONNECTOR_ID_LVDS) ||
+                               (connector_id == CONNECTOR_ID_EDP))
+                       return true;
+       }
+
+       return false;
+}
+
+bool dal_adapter_service_get_embedded_panel_info(
+       struct adapter_service *as,
+       struct embedded_panel_info *info)
+{
+       enum bp_result result;
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       if (info == NULL)
+               /*TODO: add DALASSERT_MSG here*/
+               return false;
+
+       result = dcb->funcs->get_embedded_panel_info(dcb, info);
+
+       return result == BP_RESULT_OK;
+}
+
+bool dal_adapter_service_enum_embedded_panel_patch_mode(
+       struct adapter_service *as,
+       uint32_t index,
+       struct embedded_panel_patch_mode *mode)
+{
+       enum bp_result result;
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       if (mode == NULL)
+               /*TODO: add DALASSERT_MSG here*/
+               return false;
+
+       result = dcb->funcs->enum_embedded_panel_patch_mode(dcb, index, mode);
+
+       return result == BP_RESULT_OK;
+}
+
+bool dal_adapter_service_get_faked_edid_len(
+       struct adapter_service *as,
+       uint32_t *len)
+{
+       enum bp_result result;
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       result = dcb->funcs->get_faked_edid_len(dcb, len);
+
+       return result == BP_RESULT_OK;
+}
+
+bool dal_adapter_service_get_faked_edid_buf(
+       struct adapter_service *as,
+       uint8_t *buf,
+       uint32_t len)
+{
+       enum bp_result result;
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       result = dcb->funcs->get_faked_edid_buf(dcb, buf, len);
+
+       return result == BP_RESULT_OK;
+
+}
+
+/*
+ * dal_adapter_service_is_fusion
+ *
+ * Is this Fusion ASIC
+ */
+bool dal_adapter_service_is_fusion(struct adapter_service *as)
+{
+       return as->asic_cap->caps.IS_FUSION;
+}
+
+/*
+ * dal_adapter_service_is_dfsbyass_dynamic
+ *
+ *
+ **/
+bool dal_adapter_service_is_dfsbyass_dynamic(struct adapter_service *as)
+{
+       return as->asic_cap->caps.DFSBYPASS_DYNAMIC_SUPPORT;
+}
+
+/*
+ * dal_adapter_service_should_optimize
+ *
+ * @brief Reports whether driver settings allow requested optimization
+ *
+ * @param
+ * as: adapter service handler
+ * feature: for which optimization is validated
+ *
+ * @return
+ * true if requested feature can be optimized
+ */
+bool dal_adapter_service_should_optimize(
+               struct adapter_service *as, enum optimization_feature feature)
+{
+       uint32_t supported_optimization = 0;
+       struct dal_asic_runtime_flags flags;
+
+       if (!dal_adapter_service_get_feature_value(FEATURE_OPTIMIZATION,
+                       &supported_optimization, sizeof(uint32_t)))
+               return false;
+
+       /* Retrieve ASIC runtime flags */
+       flags = dal_adapter_service_get_asic_runtime_flags(as);
+
+       /* Check runtime flags against different optimization features */
+       switch (feature) {
+       case OF_SKIP_HW_PROGRAMMING_ON_ENABLED_EMBEDDED_DISPLAY:
+               if (!flags.flags.bits.OPTIMIZED_DISPLAY_PROGRAMMING_ON_BOOT)
+                       return false;
+               break;
+
+       case OF_SKIP_RESET_OF_ALL_HW_ON_S3RESUME:
+               if (as->integrated_info == NULL ||
+                               !flags.flags.bits.SKIP_POWER_DOWN_ON_RESUME)
+                       return false;
+               break;
+       case OF_SKIP_POWER_DOWN_INACTIVE_ENCODER:
+               if (!dal_adapter_service_get_asic_runtime_flags(as).flags.bits.
+                       SKIP_POWER_DOWN_ON_RESUME)
+                       return false;
+               break;
+       default:
+               break;
+       }
+
+       return (supported_optimization & feature) != 0;
+}
+
+/*
+ * dal_adapter_service_is_in_accelerated_mode
+ *
+ * @brief Determine if driver is in accelerated mode
+ *
+ * @param
+ * as: Adapter Service handler
+ *
+ * @out
+ * True if driver is in accelerated mode, false otherwise.
+ */
+bool dal_adapter_service_is_in_accelerated_mode(struct adapter_service *as)
+{
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       return dcb->funcs->is_accelerated_mode(dcb);
+}
+
+struct ddc *dal_adapter_service_obtain_ddc_from_i2c_info(
+       struct adapter_service *as,
+       struct graphics_object_i2c_info *info)
+{
+       struct gpio_ddc_hw_info hw_info = {
+               info->i2c_hw_assist,
+               info->i2c_line };
+       return dal_gpio_service_create_ddc(as->gpio_service,
+               info->gpio_info.clk_a_register_index,
+               (1 << info->gpio_info.clk_a_shift), &hw_info);
+}
+
+struct bdf_info dal_adapter_service_get_adapter_info(struct adapter_service 
*as)
+{
+       return as->bdf_info;
+}
+
+/*
+ * dal_adapter_service_should_psr_skip_wait_for_pll_lock
+ *
+ * @brief Determine if this ASIC needs to wait on PLL lock bit
+ *
+ * @param
+ * as: Adapter Service handle
+ *
+ * @out
+ * True if ASIC does not need to wait for PLL lock bit, i.e. skip the wait.
+ */
+bool dal_adapter_service_should_psr_skip_wait_for_pll_lock(
+       struct adapter_service *as)
+{
+       return as->asic_cap->caps.SKIP_PSR_WAIT_FOR_PLL_LOCK_BIT;
+}
+
+bool dal_adapter_service_is_lid_open(struct adapter_service *as)
+{
+       bool is_lid_open = false;
+       struct platform_info_params params;
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       params.data = &is_lid_open;
+       params.method = PM_GET_LID_STATE;
+
+       if ((PM_GET_LID_STATE & as->platform_methods_mask) &&
+               dm_get_platform_info(as->ctx, &params))
+               return is_lid_open;
+
+#if defined(CONFIG_DRM_AMD_DAL_VBIOS_PRESENT)
+       return dcb->funcs->is_lid_open(dcb);
+#else
+       return false;
+#endif
+}
+
+bool dal_adapter_service_get_panel_backlight_default_levels(
+       struct adapter_service *as,
+       struct panel_backlight_levels *levels)
+{
+       if (!as->backlight_caps_initialized)
+               return false;
+
+       levels->ac_level_percentage = as->ac_level_percentage;
+       levels->dc_level_percentage = as->dc_level_percentage;
+       return true;
+}
+
+bool dal_adapter_service_get_panel_backlight_boundaries(
+       struct adapter_service *as,
+       struct panel_backlight_boundaries *boundaries)
+{
+       if (!as->backlight_caps_initialized)
+               return false;
+       if (boundaries != NULL) {
+               boundaries->min_signal_level = as->backlight_8bit_lut[0];
+               boundaries->max_signal_level =
+                       as->backlight_8bit_lut[SIZEOF_BACKLIGHT_LUT - 1];
+               return true;
+       }
+       return false;
+}
+
+
+uint32_t dal_adapter_service_get_view_port_pixel_granularity(
+       struct adapter_service *as)
+{
+       return as->asic_cap->data[ASIC_DATA_VIEWPORT_PIXEL_GRANULARITY];
+}
+
+/**
+ * Get number of paths per DP 1.2 connector from the runtime parameter if it
+ * exists.
+ * A check to see if MST is supported for the generation of ASIC is done
+ *
+ * \return
+ *    Number of paths per DP 1.2 connector is exists in runtime parameters
+ *    or ASIC cap
+ */
+uint32_t dal_adapter_service_get_num_of_path_per_dp_mst_connector(
+               struct adapter_service *as)
+{
+       if (as->asic_cap->caps.DP_MST_SUPPORTED == 0) {
+               /* ASIC doesn't support DP MST at all */
+               return 0;
+       }
+
+       return as->asic_cap->data[ASIC_DATA_PATH_NUM_PER_DPMST_CONNECTOR];
+}
+
+uint32_t dal_adapter_service_get_num_of_underlays(
+               struct adapter_service *as)
+{
+       return as->asic_cap->data[ASIC_DATA_NUM_OF_VIDEO_PLANES];
+}
+
+bool dal_adapter_service_get_encoder_cap_info(
+               struct adapter_service *as,
+               struct graphics_object_id id,
+               struct graphics_object_encoder_cap_info *info)
+{
+       struct bp_encoder_cap_info bp_cap_info = {0};
+       enum bp_result result;
+       struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as);
+
+       if (NULL == info) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       /*
+        * Retrieve Encoder Capability Information from VBIOS and store the
+        * call result (success or fail)
+        * Info from VBIOS about HBR2 has two fields:
+        *
+        * - dpHbr2Cap: indicates supported/not supported by HW Encoder
+        * - dpHbr2En : indicates DP spec compliant/not compliant
+        */
+       result = dcb->funcs->get_encoder_cap_info(dcb, id, &bp_cap_info);
+
+       /* Set dp_hbr2_validated flag (it's equal to Enable) */
+       info->dp_hbr2_validated = bp_cap_info.DP_HBR2_EN;
+
+       if (result == BP_RESULT_OK) {
+               info->dp_hbr2_cap = bp_cap_info.DP_HBR2_CAP;
+               return true;
+       }
+
+       return false;
+}
+
+bool dal_adapter_service_is_mc_tuning_req(struct adapter_service *as)
+{
+       return as->asic_cap->caps.NEED_MC_TUNING ? true : false;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.h 
b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.h
new file mode 100644
index 000000000000..60464e89cc5b
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_ADAPTER_SERVICE_H__
+#define __DAL_ADAPTER_SERVICE_H__
+
+/* Include */
+#include "dc_bios_types.h"
+#include "include/adapter_service_interface.h"
+#include "wireless_data_source.h"
+
+/*
+ * Forward declaration
+ */
+struct gpio_service;
+struct asic_cap;
+
+
+/* Adapter service */
+struct adapter_service {
+       struct dc_context *ctx;
+       struct asic_capability *asic_cap;
+       struct dc_bios *dcb_internal;/* created by DC */
+       struct dc_bios *dcb_override;/* supplied by creator of DC */
+       enum dce_environment dce_environment;
+       struct gpio_service *gpio_service;
+       struct i2caux *i2caux;
+       struct wireless_data wireless_data;
+       struct hw_ctx_adapter_service *hw_ctx;
+       struct integrated_info *integrated_info;
+       struct bdf_info bdf_info;
+       uint32_t platform_methods_mask;
+       uint32_t ac_level_percentage;
+       uint32_t dc_level_percentage;
+       uint32_t backlight_caps_initialized;
+       uint32_t backlight_8bit_lut[SIZEOF_BACKLIGHT_LUT];
+};
+
+/* Type of feature with its runtime parameter and default value */
+struct feature_source_entry {
+       enum adapter_feature_id feature_id;
+       uint32_t default_value;
+       bool is_boolean_type;
+};
+
+/* Stores entire ASIC features by sets */
+extern uint32_t adapter_feature_set[];
+
+#endif /* __DAL_ADAPTER_SERVICE_H__ */
diff --git 
a/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.c 
b/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.c
new file mode 100644
index 000000000000..f10bee6f2b83
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 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_dce110.h"
+
+#include "include/logger_interface.h"
+#include "include/grph_object_id.h"
+
+#include "dce/dce_11_0_d.h"
+#include "dce/dce_11_0_sh_mask.h"
+
+#ifndef mmCC_DC_HDMI_STRAPS
+#define mmCC_DC_HDMI_STRAPS 0x4819
+#define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40
+#define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6
+#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700
+#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8
+#endif
+
+static const struct graphics_object_id invalid_go = {
+       0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN, 0
+};
+
+/* Macro */
+#define AUDIO_STRAPS_HDMI_ENABLE 0x2
+
+#define FROM_HW_CTX(ptr) \
+       container_of((ptr), struct hw_ctx_adapter_service_dce110, base)
+
+static const uint32_t audio_index_reg_offset[] = {
+       /*CZ has 3 DIGs but 4 audio endpoints*/
+       mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX,
+       mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_INDEX,
+       mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_INDEX,
+       mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_INDEX
+};
+
+static const uint32_t audio_data_reg_offset[] = {
+       mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA,
+       mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_DATA,
+       mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_DATA,
+       mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_DATA,
+};
+
+enum {
+       MAX_NUMBER_OF_AUDIO_PINS = 4
+};
+
+static void destruct(
+       struct hw_ctx_adapter_service_dce110 *hw_ctx)
+{
+       /* There is nothing to destruct at the moment */
+       dal_adapter_service_destruct_hw_ctx(&hw_ctx->base);
+}
+
+static void destroy(
+       struct hw_ctx_adapter_service *ptr)
+{
+       struct hw_ctx_adapter_service_dce110 *hw_ctx =
+               FROM_HW_CTX(ptr);
+
+       destruct(hw_ctx);
+
+       dm_free(ptr->ctx, hw_ctx);
+}
+
+/*
+ * enum_audio_object
+ *
+ * @brief enumerate audio object
+ *
+ * @param
+ * const struct hw_ctx_adapter_service *hw_ctx - [in] provides num of endpoints
+ * uint32_t index - [in] audio index
+ *
+ * @return
+ * grphic object id
+ */
+static struct graphics_object_id enum_audio_object(
+       const struct hw_ctx_adapter_service *hw_ctx,
+       uint32_t index)
+{
+       uint32_t number_of_connected_audio_endpoints =
+               FROM_HW_CTX(hw_ctx)->number_of_connected_audio_endpoints;
+
+       if (index >= number_of_connected_audio_endpoints ||
+                       number_of_connected_audio_endpoints == 0)
+               return invalid_go;
+       else
+               return dal_graphics_object_id_init(
+                       AUDIO_ID_INTERNAL_AZALIA,
+                       (enum object_enum_id)(index + 1),
+                       OBJECT_TYPE_AUDIO);
+}
+
+static uint32_t get_number_of_connected_audio_endpoints_multistream(
+               struct dc_context *ctx)
+{
+       uint32_t num_connected_audio_endpoints = 0;
+       uint32_t i;
+       uint32_t default_config =
+       ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT;
+
+       /* find the total number of streams available via the
+        * AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT
+        * registers (one for each pin) starting from pin 1
+        * up to the max number of audio pins.
+        * We stop on the first pin where
+        * PORT_CONNECTIVITY == 1 (as instructed by HW team).
+        */
+       for (i = 0; i < MAX_NUMBER_OF_AUDIO_PINS; i++) {
+               uint32_t value = 0;
+
+               set_reg_field_value(value,
+                       default_config,
+                       AZALIA_F0_CODEC_ENDPOINT_INDEX,
+                       AZALIA_ENDPOINT_REG_INDEX);
+
+               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_dce110 *hw_ctx_dce11 =
+                       FROM_HW_CTX(hw_ctx);
+       /* Allow DP audio all the time
+        * without additional pinstrap check on Fusion */
+
+
+       {
+               uint32_t value = 0;
+               uint32_t field = 0;
+
+               value = 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 DCE110 */
+}
+
+static const struct hw_ctx_adapter_service_funcs funcs = {
+       .destroy = destroy,
+       .power_up = power_up,
+       .enum_fake_path_resource = NULL,
+       .enum_stereo_sync_object = NULL,
+       .enum_sync_output_object = NULL,
+       .enum_audio_object = enum_audio_object,
+       .update_audio_connectivity = update_audio_connectivity
+};
+
+static bool construct(
+       struct hw_ctx_adapter_service_dce110 *hw_ctx,
+       struct dc_context *ctx)
+{
+       if (!dal_adapter_service_construct_hw_ctx(&hw_ctx->base, ctx)) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       hw_ctx->base.funcs = &funcs;
+       hw_ctx->number_of_connected_audio_endpoints = 0;
+
+       return true;
+}
+
+struct hw_ctx_adapter_service *
+       dal_adapter_service_create_hw_ctx_dce110(
+                       struct dc_context *ctx)
+{
+       struct hw_ctx_adapter_service_dce110 *hw_ctx =
+                       dm_alloc(ctx, sizeof(struct 
hw_ctx_adapter_service_dce110));
+
+       if (!hw_ctx) {
+               ASSERT_CRITICAL(false);
+               return NULL;
+       }
+
+       if (construct(hw_ctx, ctx))
+               return &hw_ctx->base;
+
+       ASSERT_CRITICAL(false);
+
+       dm_free(ctx, hw_ctx);
+
+       return NULL;
+}
diff --git 
a/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.h 
b/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.h
new file mode 100644
index 000000000000..092b67173dc4
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_CTX_ADAPTER_SERVICE_DCE110_H__
+#define __DAL_HW_CTX_ADAPTER_SERVICE_DCE110_H__
+
+struct hw_ctx_adapter_service_dce110 {
+       struct hw_ctx_adapter_service base;
+       uint32_t number_of_connected_audio_endpoints;
+};
+
+struct hw_ctx_adapter_service *
+       dal_adapter_service_create_hw_ctx_dce110(
+                       struct dc_context *ctx);
+
+#endif /* __DAL_HW_CTX_ADAPTER_SERVICE_DCE110_H__ */
+
+
diff --git 
a/drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.c 
b/drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.c
new file mode 100644
index 000000000000..4f5f0403af84
--- /dev/null
+++ 
b/drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2012-16 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+/* FPGA Diagnostics version of AS HW CTX. */
+
+#include "dm_services.h"
+
+#include "../hw_ctx_adapter_service.h"
+
+#include "hw_ctx_adapter_service_diag.h"
+
+#include "include/logger_interface.h"
+#include "include/grph_object_id.h"
+
+static const struct graphics_object_id invalid_go = {
+       0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN
+};
+
+static void destroy(
+       struct hw_ctx_adapter_service *hw_ctx)
+{
+}
+
+static bool power_up(
+       struct hw_ctx_adapter_service *hw_ctx)
+{
+       return true;
+}
+
+static struct graphics_object_id enum_fake_path_resource(
+       const struct hw_ctx_adapter_service *hw_ctx,
+       uint32_t index)
+{
+       return invalid_go;
+}
+
+static struct graphics_object_id enum_stereo_sync_object(
+       const struct hw_ctx_adapter_service *hw_ctx,
+       uint32_t index)
+{
+       return invalid_go;
+}
+
+static struct graphics_object_id enum_sync_output_object(
+       const struct hw_ctx_adapter_service *hw_ctx,
+       uint32_t index)
+{
+       return invalid_go;
+}
+
+static struct graphics_object_id enum_audio_object(
+       const struct hw_ctx_adapter_service *hw_ctx,
+       uint32_t index)
+{
+       return invalid_go;
+}
+
+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)
+{
+}
+
+static const struct hw_ctx_adapter_service_funcs funcs = {
+       destroy,
+       power_up,
+       enum_fake_path_resource,
+       enum_stereo_sync_object,
+       enum_sync_output_object,
+       enum_audio_object,
+       update_audio_connectivity
+};
+
+static bool construct(
+       struct hw_ctx_adapter_service *hw_ctx,
+       struct dc_context *ctx)
+
+{
+       if (!dal_adapter_service_construct_hw_ctx(hw_ctx, ctx)) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       hw_ctx->funcs = &funcs;
+
+       return true;
+}
+
+struct hw_ctx_adapter_service *dal_adapter_service_create_hw_ctx_diag(
+       struct dc_context *ctx)
+{
+       struct hw_ctx_adapter_service *hw_ctx = dm_alloc(ctx,
+                       sizeof(*hw_ctx));
+
+       if (!hw_ctx) {
+               ASSERT_CRITICAL(false);
+               return NULL;
+       }
+
+       if (construct(hw_ctx, ctx))
+               return hw_ctx;
+
+       ASSERT_CRITICAL(false);
+
+       dm_free(ctx, hw_ctx);
+
+       return NULL;
+}
+
+/*****************************************************************************/
diff --git 
a/drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.h 
b/drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.h
new file mode 100644
index 000000000000..39ae7524506c
--- /dev/null
+++ 
b/drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2012-16 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 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_DIAG_H__
+#define __DAL_HW_CTX_ADAPTER_SERVICE_DIAG_H__
+
+
+struct hw_ctx_adapter_service *dal_adapter_service_create_hw_ctx_diag(
+               struct dc_context *ctx);
+
+#endif /* __DAL_HW_CTX_ADAPTER_SERVICE_DIAG_H__ */
diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.c 
b/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.c
new file mode 100644
index 000000000000..12eabe0c3f89
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+#include "include/adapter_service_types.h"
+#include "include/grph_object_id.h"
+#include "hw_ctx_adapter_service.h"
+
+static const struct graphics_object_id invalid_go = {
+       0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN
+};
+
+static void destroy(
+       struct hw_ctx_adapter_service *hw_ctx)
+{
+       /* Attention!
+        * You must override impl method in derived class */
+       BREAK_TO_DEBUGGER();
+}
+
+static bool power_up(
+       struct hw_ctx_adapter_service *hw_ctx)
+{
+       /* Attention!
+        * You must override impl method in derived class */
+       BREAK_TO_DEBUGGER();
+
+       return false;
+}
+
+static struct graphics_object_id enum_fake_path_resource(
+       const struct hw_ctx_adapter_service *hw_ctx,
+       uint32_t index)
+{
+       return invalid_go;
+}
+
+static struct graphics_object_id enum_stereo_sync_object(
+       const struct hw_ctx_adapter_service *hw_ctx,
+       uint32_t index)
+{
+       return invalid_go;
+}
+
+static struct graphics_object_id enum_sync_output_object(
+       const struct hw_ctx_adapter_service *hw_ctx,
+       uint32_t index)
+{
+       return invalid_go;
+}
+
+static struct graphics_object_id enum_audio_object(
+       const struct hw_ctx_adapter_service *hw_ctx,
+       uint32_t index)
+{
+       /* by default, we only allow one audio */
+
+       if (index > 0)
+               return invalid_go;
+       else if (hw_ctx->cached_audio_straps == AUDIO_STRAPS_NOT_ALLOWED)
+               return invalid_go;
+       else
+               return dal_graphics_object_id_init(
+                       AUDIO_ID_INTERNAL_AZALIA,
+                       ENUM_ID_1,
+                       OBJECT_TYPE_AUDIO);
+}
+
+static void update_audio_connectivity(
+       struct hw_ctx_adapter_service *hw_ctx,
+       uint32_t number_of_audio_capable_display_path,
+       uint32_t number_of_controllers)
+{
+       /* Attention!
+        * You must override impl method in derived class */
+       BREAK_TO_DEBUGGER();
+}
+
+static const struct hw_ctx_adapter_service_funcs funcs = {
+       destroy,
+       power_up,
+       enum_fake_path_resource,
+       enum_stereo_sync_object,
+       enum_sync_output_object,
+       enum_audio_object,
+       update_audio_connectivity
+};
+
+bool dal_adapter_service_construct_hw_ctx(
+       struct hw_ctx_adapter_service *hw_ctx,
+       struct dc_context *ctx)
+{
+
+       hw_ctx->ctx = ctx;
+       hw_ctx->funcs = &funcs;
+       hw_ctx->cached_audio_straps = AUDIO_STRAPS_NOT_ALLOWED;
+
+       return true;
+}
+
+union audio_support dal_adapter_service_hw_ctx_get_audio_support(
+       const struct hw_ctx_adapter_service *hw_ctx)
+{
+       union audio_support result;
+
+       result.raw = 0;
+
+       switch (hw_ctx->cached_audio_straps) {
+       case AUDIO_STRAPS_DP_HDMI_AUDIO:
+               result.bits.HDMI_AUDIO_NATIVE = true;
+               /* do not break ! */
+       case AUDIO_STRAPS_DP_HDMI_AUDIO_ON_DONGLE:
+               result.bits.HDMI_AUDIO_ON_DONGLE = true;
+               /* do not break ! */
+       case AUDIO_STRAPS_DP_AUDIO_ALLOWED:
+               result.bits.DP_AUDIO = true;
+               break;
+       default:
+               break;
+       }
+
+       return result;
+}
+
+void dal_adapter_service_destruct_hw_ctx(
+       struct hw_ctx_adapter_service *hw_ctx)
+{
+       /* There is nothing to destruct at the moment */
+}
+
+void dal_adapter_service_destroy_hw_ctx(
+       struct hw_ctx_adapter_service **ptr)
+{
+       if (!ptr || !*ptr) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
+       (*ptr)->funcs->destroy(*ptr);
+
+       *ptr = NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.h 
b/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.h
new file mode 100644
index 000000000000..f98c2d428b2a
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_CTX_ADAPTER_SERVICE_H__
+#define __DAL_HW_CTX_ADAPTER_SERVICE_H__
+
+enum audio_straps {
+       AUDIO_STRAPS_NOT_ALLOWED = 0,
+       AUDIO_STRAPS_DP_AUDIO_ALLOWED,
+       AUDIO_STRAPS_DP_HDMI_AUDIO_ON_DONGLE,
+       AUDIO_STRAPS_DP_HDMI_AUDIO
+};
+
+struct hw_ctx_adapter_service;
+
+struct hw_ctx_adapter_service_funcs {
+       void (*destroy)(
+               struct hw_ctx_adapter_service *hw_ctx);
+       /* Initializes relevant HW registers
+        * and caches relevant data from HW registers */
+       bool (*power_up)(
+               struct hw_ctx_adapter_service *hw_ctx);
+       /* Enumerate fake path resources */
+       struct graphics_object_id (*enum_fake_path_resource)(
+               const struct hw_ctx_adapter_service *hw_ctx,
+               uint32_t index);
+       /* Enumerate stereo sync objects */
+       struct graphics_object_id (*enum_stereo_sync_object)(
+               const struct hw_ctx_adapter_service *hw_ctx,
+               uint32_t index);
+       /* Enumerate (H/V) sync output objects */
+       struct graphics_object_id (*enum_sync_output_object)(
+               const struct hw_ctx_adapter_service *hw_ctx,
+               uint32_t index);
+       /* Enumerate audio objects */
+       struct graphics_object_id (*enum_audio_object)(
+               const struct hw_ctx_adapter_service *hw_ctx,
+               uint32_t index);
+       void (*update_audio_connectivity)(
+               struct hw_ctx_adapter_service *hw_ctx,
+               uint32_t number_of_audio_capable_display_path,
+               uint32_t number_of_controllers);
+};
+
+struct hw_ctx_adapter_service {
+       struct dc_context *ctx;
+       const struct hw_ctx_adapter_service_funcs *funcs;
+       enum audio_straps cached_audio_straps;
+};
+
+bool dal_adapter_service_construct_hw_ctx(
+       struct hw_ctx_adapter_service *hw_ctx,
+       struct dc_context *ctx);
+
+union audio_support dal_adapter_service_hw_ctx_get_audio_support(
+       const struct hw_ctx_adapter_service *hw_ctx);
+
+void dal_adapter_service_destruct_hw_ctx(
+       struct hw_ctx_adapter_service *hw_ctx);
+
+void dal_adapter_service_destroy_hw_ctx(
+       struct hw_ctx_adapter_service **ptr);
+
+#endif /* __DAL_HW_CTX_ADAPTER_SERVICE_H__ */
diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.c 
b/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.c
new file mode 100644
index 000000000000..0b1151ec5a2c
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 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 "adapter_service.h"
+#include "wireless_data_source.h"
+
+#include "atom.h"
+
+/*construct wireless data*/
+bool wireless_data_init(struct wireless_data *data,
+               struct dc_bios *dcb,
+               struct wireless_init_data *init_data)
+{
+       struct firmware_info info;
+
+       if (data == NULL || dcb == NULL || init_data == NULL) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       data->miracast_connector_enable = false;
+       data->wireless_disp_path_enable = false;
+       data->wireless_enable = false;
+
+       /* Wireless it not supported if VCE is not supported */
+       if (!init_data->vce_supported)
+               return true;
+
+       if (init_data->miracast_target_required)
+               data->miracast_connector_enable = true;
+
+       /*
+        * If override is in place for platform support, we will both
+        * enable wireless display as a feature (i.e. CCC aspect) and
+        * enable the wireless display path without any further checks.
+        */
+       if (init_data->platform_override) {
+               data->wireless_enable = true;
+               data->wireless_disp_path_enable = true;
+       } else {
+               /*
+                * Check if SBIOS sets remote display enable, exposed
+                * through VBIOS. This is only valid for APU, not dGPU
+                */
+               dcb->funcs->get_firmware_info(dcb, &info);
+
+               if ((REMOTE_DISPLAY_ENABLE == info.remote_display_config) &&
+                               init_data->fusion) {
+                       data->wireless_enable = true;
+                       data->wireless_disp_path_enable = true;
+               }
+       }
+
+       /*
+        * If remote display path override is enabled, we enable just the
+        * remote display path. This is mainly used for testing purposes
+        */
+       if (init_data->remote_disp_path_override)
+               data->wireless_disp_path_enable = true;
+
+       return true;
+}
+
+uint8_t wireless_get_clocks_num(
+       struct adapter_service *as)
+{
+       if (as->wireless_data.wireless_enable ||
+               as->wireless_data.wireless_disp_path_enable)
+               return 1;
+       else
+               return 0;
+}
+
+static uint8_t wireless_get_encoders_num(
+       struct adapter_service *as)
+{
+       if (as->wireless_data.wireless_enable ||
+               as->wireless_data.wireless_disp_path_enable)
+               return 1;
+       else
+               return 0;
+}
+
+uint8_t wireless_get_connectors_num(
+       struct adapter_service *as)
+{
+       uint8_t wireless_connectors_num = 0;
+
+       if (as->wireless_data.wireless_enable &&
+               as->wireless_data.miracast_connector_enable)
+               wireless_connectors_num++;
+
+       if (as->wireless_data.wireless_disp_path_enable)
+               wireless_connectors_num++;
+
+       return wireless_connectors_num;
+}
+
+struct graphics_object_id wireless_get_connector_id(
+       struct adapter_service *as,
+       uint8_t index)
+{
+       struct graphics_object_id unknown_object_id =
+                       dal_graphics_object_id_init(
+                               0,
+                               ENUM_ID_UNKNOWN,
+                               OBJECT_TYPE_UNKNOWN);
+
+       if (!as->wireless_data.wireless_enable &&
+               !as->wireless_data.wireless_disp_path_enable)
+               return unknown_object_id;
+
+       else if (!as->wireless_data.miracast_connector_enable)
+               return dal_graphics_object_id_init(
+                       CONNECTOR_ID_WIRELESS,
+                       ENUM_ID_1,
+                       OBJECT_TYPE_CONNECTOR);
+
+       switch (index) {
+       case 0:
+               return dal_graphics_object_id_init(
+                       CONNECTOR_ID_WIRELESS,
+                       ENUM_ID_1,
+                       OBJECT_TYPE_CONNECTOR);
+               break;
+       case 1:
+               return dal_graphics_object_id_init(
+                       CONNECTOR_ID_MIRACAST,
+                       ENUM_ID_1,
+                       OBJECT_TYPE_CONNECTOR);
+               break;
+       default:
+               return unknown_object_id;
+       }
+}
+
+uint8_t wireless_get_srcs_num(
+       struct adapter_service *as,
+       struct graphics_object_id id)
+{
+       switch (id.type) {
+       case OBJECT_TYPE_CONNECTOR:
+               return wireless_get_encoders_num(as);
+       case OBJECT_TYPE_ENCODER:
+               return 1;
+
+       default:
+               ASSERT_CRITICAL(false);
+               break;
+       }
+
+       return 0;
+}
+
+struct graphics_object_id wireless_get_src_obj_id(
+       struct adapter_service *as,
+       struct graphics_object_id id,
+       uint8_t index)
+{
+       if (index < wireless_get_srcs_num(as, id)) {
+               switch (id.type) {
+               case OBJECT_TYPE_CONNECTOR:
+                       return dal_graphics_object_id_init(
+                                       ENCODER_ID_INTERNAL_WIRELESS,
+                                       ENUM_ID_1,
+                                       OBJECT_TYPE_ENCODER);
+                       break;
+               case OBJECT_TYPE_ENCODER:
+                       return dal_graphics_object_id_init(
+                                       0,
+                                       ENUM_ID_1,
+                                       OBJECT_TYPE_GPU);
+                       break;
+               default:
+                       ASSERT_CRITICAL(false);
+                       break;
+               }
+       }
+
+       return dal_graphics_object_id_init(
+                       0,
+                       ENUM_ID_UNKNOWN,
+                       OBJECT_TYPE_UNKNOWN);
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.h 
b/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.h
new file mode 100644
index 000000000000..b64089e3960e
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_WIRELESS_DATA_SOURCE_H__
+#define __DAL_WIRELESS_DATA_SOURCE_H__
+
+/* Include */
+#include "include/grph_object_id.h"
+
+/*
+ * Forward declaration
+ */
+struct adapter_service;
+struct dc_bios;
+
+/* Wireless data init structure */
+struct wireless_init_data {
+       bool fusion; /* Fusion flag */
+       bool platform_override; /* Override for platform BIOS option */
+       bool remote_disp_path_override; /* Override enabling wireless path */
+       bool vce_supported; /* Existence of VCE block on this DCE */
+       bool miracast_target_required; /* OS requires Miracast target */
+};
+
+/* Wireless data */
+struct wireless_data {
+       bool wireless_enable;
+       bool wireless_disp_path_enable;
+       bool miracast_connector_enable;
+};
+
+
+/*construct wireless data*/
+bool wireless_data_init(
+       struct wireless_data *data,
+       struct dc_bios *dcb,
+       struct wireless_init_data *init_data);
+
+uint8_t wireless_get_clocks_num(
+       struct adapter_service *as);
+
+uint8_t wireless_get_connectors_num(
+       struct adapter_service *as);
+
+struct graphics_object_id wireless_get_connector_id(
+       struct adapter_service *as,
+       uint8_t connector_index);
+
+uint8_t wireless_get_srcs_num(
+       struct adapter_service *as,
+       struct graphics_object_id id);
+
+struct graphics_object_id wireless_get_src_obj_id(
+       struct adapter_service *as,
+       struct graphics_object_id id,
+       uint8_t index);
+
+#endif /* __DAL_WIRELESS_DATA_SOURCE_H__ */
-- 
2.1.4

Reply via email to