summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarry Wentland <harry.wentland@amd.com>2015-07-31 21:30:28 -0400
committerAlex Deucher <alexander.deucher@amd.com>2015-09-21 17:45:15 -0400
commitf8846a938eff8610d3a0e42863890fbd0dee0b41 (patch)
tree0970965b7503f583e8f8ac80ba229cad1360a2c9
parent7be25cce3466809be0b38e62ed6105281cfd7445 (diff)
amd/dal: Display Path
The core (anchor) of Display Path are Connector and Encoder – these actually define a Display Path. The rest of the objects are added and removed to/from Display Path on the fly – whenever DAL requires to setup or reset the video stream. SW Layer /===============================================================\ | Timing Asic | | Service Capability | | | | Display Display Adapter | | Path Capability Service | | Service | |---------------------------------------------------------------| | GPIO IRQ I2cAux BIOS | | Service Manager Parser | | | | Connector Encoder Audio GPU Controller | \===============================================================/ HW Layer Signed-off-by: Harry Wentland <harry.wentland@amd.com>
-rw-r--r--drivers/gpu/drm/amd/dal/Makefile2
-rw-r--r--drivers/gpu/drm/amd/dal/display_path/Makefile10
-rw-r--r--drivers/gpu/drm/amd/dal/display_path/display_path.c1161
-rw-r--r--drivers/gpu/drm/amd/dal/display_path/display_path.h110
-rw-r--r--drivers/gpu/drm/amd/dal/display_path/stream_context.c181
-rw-r--r--drivers/gpu/drm/amd/dal/include/display_path_interface.h436
-rw-r--r--drivers/gpu/drm/amd/dal/include/display_path_types.h132
-rw-r--r--drivers/gpu/drm/amd/dal/include/link_service_interface.h202
8 files changed, 2233 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/dal/Makefile b/drivers/gpu/drm/amd/dal/Makefile
index dfe302dd7dbe..fe54c46125ad 100644
--- a/drivers/gpu/drm/amd/dal/Makefile
+++ b/drivers/gpu/drm/amd/dal/Makefile
@@ -8,7 +8,7 @@ AMDDALPATH = $(RELATIVE_AMD_DAL_PATH)
subdir-ccflags-y += -I$(AMDDALPATH)/ -I$(AMDDALPATH)/include -DDAL_CZ_BRINGUP
DAL_LIBS = adapter amdgpu_dm audio asic_capability basics bios connector \
- controller dcs encoder gpio gpu i2caux irq timing_service
+ controller dcs display_path encoder gpio gpu i2caux irq timing_service
AMD_DAL = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DAL_PATH)/,$(DAL_LIBS)))
diff --git a/drivers/gpu/drm/amd/dal/display_path/Makefile b/drivers/gpu/drm/amd/dal/display_path/Makefile
new file mode 100644
index 000000000000..78c200c3b418
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/display_path/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the 'display_path' sub-component of DAL.
+# It provides the control and status of HW adapter resources,
+# that are global for the ASIC and sharable between pipes.
+
+DISPLAY_PATH = display_path.o stream_context.o
+
+AMD_DAL_DISPLAY_PATH = $(addprefix $(AMDDALPATH)/display_path/,$(DISPLAY_PATH))
+
+AMD_DAL_FILES += $(AMD_DAL_DISPLAY_PATH)
diff --git a/drivers/gpu/drm/amd/dal/display_path/display_path.c b/drivers/gpu/drm/amd/dal/display_path/display_path.c
new file mode 100644
index 000000000000..ee2d13132fe5
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/display_path/display_path.c
@@ -0,0 +1,1161 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dal_services.h"
+
+#include "include/connector_interface.h"
+#include "include/link_service_interface.h"
+#include "include/audio_interface.h"
+#include "include/controller_interface.h"
+#include "include/dcs_interface.h"
+#include "include/clock_source_interface.h"
+#include "include/encoder_interface.h"
+#include "include/display_path_interface.h"
+#include "include/vector.h"
+
+#include "display_path.h"
+
+DAL_VECTOR_AT_INDEX(display_path_plane, struct display_path_plane *)
+DAL_VECTOR_APPEND(display_path_plane, struct display_path_plane *)
+
+static bool allocate_mpo_resources(struct display_path *path)
+{
+ /* CZ: 3 Primary and 1 Underlay = 4
+ * TODO: this value should be received from Asic Caps
+ * No hardcode should be anywhere
+ * Proposal here is to support arbitrary number of planes by display
+ * path */
+ const uint32_t max_planes_num = 4;
+
+ /* will be storing structures, not pointers */
+ path->planes =
+ dal_vector_create(
+ max_planes_num,
+ sizeof(struct display_path_plane));
+
+ if (NULL == path->planes)
+ return false;
+ else
+ return true;
+}
+
+static void free_mpo_resources(struct display_path *path)
+{
+ dal_vector_destroy(&path->planes);
+}
+
+static bool display_path_construct(struct display_path *path)
+{
+ uint32_t i;
+
+ path->number_of_links = 0;
+ dal_memset(&path->stream_contexts, 0, sizeof(path->stream_contexts));
+
+ for (i = 0; i < MAX_NUM_OF_LINKS_PER_PATH; i++)
+ path->stream_contexts[i].engine = ENGINE_ID_UNKNOWN;
+
+ path->connector = NULL;
+ path->clock_source = NULL;
+ path->alt_clock_source = NULL;
+ path->dcs = NULL;
+
+ /* TODO: GL sync*/
+ path->stereo_sync_object = NULL;
+ path->sync_output_object = NULL;
+ path->sync_output_source = SYNC_SOURCE_NONE;
+ path->sync_input_source = SYNC_SOURCE_NONE;
+
+ path->connected = false;
+ path->src_tgt_state.powered_on = DISPLAY_TRI_STATE_UNKNOWN;
+ path->src_tgt_state.src_blanked = DISPLAY_TRI_STATE_UNKNOWN;
+ path->src_tgt_state.tgt_blanked = DISPLAY_TRI_STATE_UNKNOWN;
+ path->properties.raw = 0;
+ path->acquired_counter = 0;
+ path->valid = false;
+ path->display_index = INVALID_DISPLAY_INDEX;
+ path->clock_sharing_group = CLOCK_SHARING_GROUP_EXCLUSIVE;
+ path->ss_supported = false;
+ path->pixel_clock_safe_range.min_frequency = 0;
+ path->pixel_clock_safe_range.max_frequency = 0;
+ path->ddi_channel_mapping.raw = INVALID_DDI_CHANNEL_MAPPING;
+ path->device_tag.acpi_device = 0;
+ path->device_tag.dev_id.enum_id = 0;
+ path->device_tag.dev_id.device_type = DEVICE_TYPE_UNKNOWN;
+ path->drr_cfg.force_lock_on_event = 0;
+ path->drr_cfg.lock_to_master_vsync = 0;
+ path->drr_cfg.min_fps_in_microhz = 0;
+ path->static_screen_config.u_all = 0;
+
+ if (false == allocate_mpo_resources(path))
+ return false;
+ else
+ return true;
+}
+
+static void display_path_destruct(struct display_path *path)
+{
+ free_mpo_resources(path);
+}
+
+static enum signal_type calculate_upstream_signal(
+ const struct display_path *path,
+ enum signal_type downstream_signal,
+ uint32_t link_idx)
+{
+ struct encoder *encoder;
+ enum signal_type upstream_signal;
+ uint32_t common_signals;
+ struct encoder_feature_support features;
+
+ if (link_idx >= path->number_of_links)
+ return SIGNAL_TYPE_NONE;
+
+ encoder = path->stream_contexts[link_idx].encoder;
+ /* Make sure downstream object can support requested/downstream
+ * signal as an output signal.If cannot - we consider it as a failure.*/
+ if ((dal_encoder_enumerate_output_signals(encoder) & downstream_signal)
+ == 0)
+ return SIGNAL_TYPE_NONE;
+
+ /* Derive common signal for this link */
+ common_signals = dal_encoder_enumerate_input_signals(encoder);
+ if (link_idx > 0) {
+ encoder = path->stream_contexts[link_idx - 1].encoder;
+ common_signals &= dal_encoder_enumerate_output_signals(encoder);
+ encoder = path->stream_contexts[link_idx].encoder;
+ }
+
+ /* Make sure upstream link can support current signal.
+ * If not, but downstream encoder can convert signals,
+ * we choose first supported signal common for upstream link*/
+ upstream_signal = downstream_signal;
+ features = dal_encoder_get_supported_features(encoder);
+ if ((common_signals & upstream_signal) == 0) {
+ if (features.flags.bits.IS_CONVERTER)
+ /* common signals is a bitmask, we need to get least
+ * significant 1 bit to convert bitmask to signal_type
+ * enum. (x & -x) or (x & ((~x)+1)) */
+ upstream_signal = common_signals & (-common_signals);
+ else
+ upstream_signal = SIGNAL_TYPE_NONE;
+ }
+
+ return upstream_signal;
+}
+
+static enum signal_type calculate_asic_signal(
+ const struct display_path *path,
+ enum signal_type sink_signal)
+{
+ uint32_t i;
+ uint32_t current_signal;
+
+ if (path->connector == NULL)
+ return SIGNAL_TYPE_NONE;
+
+ if ((dal_connector_enumerate_output_signals(path->connector)
+ & sink_signal) == 0)
+ return SIGNAL_TYPE_NONE;
+
+ current_signal = sink_signal;
+
+ for (i = path->number_of_links; i > 0; i--) {
+ current_signal = calculate_upstream_signal(
+ path, current_signal, i - 1);
+ }
+
+ return current_signal;
+}
+static bool is_ss_forced_enable(const struct display_path *path)
+{
+ if (path->clock_source == NULL)
+ return false;
+ return (dal_clock_source_get_id(path->clock_source)
+ == CLOCK_SOURCE_ID_EXTERNAL);
+}
+
+struct display_path *dal_display_path_create(void)
+{
+ struct display_path *display_path = NULL;
+
+ display_path = dal_alloc(sizeof(struct display_path));
+ if (NULL == display_path)
+ return NULL;
+
+ if (false == display_path_construct(display_path)) {
+ dal_free(display_path);
+ return NULL;
+ }
+
+ return display_path;
+}
+
+struct display_path *dal_display_path_clone(
+ const struct display_path *origin,
+ bool copy_active_state)
+{
+ struct display_path *path = dal_display_path_create();
+
+ if (path == NULL)
+ return NULL;
+
+ /* Clean-up non-sharable pointers in new display path. */
+ dal_vector_destroy(&path->planes);
+
+ /* copy everything from origin */
+ dal_memmove(path, origin, sizeof(struct display_path));
+
+ /* All optional objects are not copied */
+ path->stereo_sync_object = NULL;
+ path->sync_output_object = NULL;
+ path->sync_output_source = SYNC_SOURCE_NONE;
+ path->sync_input_source = SYNC_SOURCE_NONE;
+
+ /* Properly clone all non-sharable pointers from "this" */
+ path->planes = dal_vector_clone(origin->planes);
+
+ ASSERT_CRITICAL(path->planes);
+
+ if (!path->planes)
+ return NULL;
+
+ path->acquired_counter = 0;
+
+ if (copy_active_state && dal_display_path_is_acquired(origin))
+ path->acquired_counter = origin->acquired_counter;
+ else
+ dal_display_path_release_resources(path);
+
+ return path;
+}
+
+void dal_display_path_destroy(struct display_path **path)
+{
+ if (!path || !*path) {
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+
+ display_path_destruct(*path);
+
+ dal_free(*path);
+
+ *path = NULL;
+
+}
+
+bool dal_display_path_validate(
+ struct display_path *path,
+ enum signal_type sink_signal)
+{
+ uint32_t i;
+
+ path->valid = false;
+ /* verify connector and at least one link present*/
+ if (path->number_of_links < 1 || path->connector == NULL) {
+ ASSERT(false);/* display path missing core components*/
+ return false;
+ }
+ /* verify encoder at each link*/
+ for (i = 0; i < path->number_of_links; i++) {
+ if (path->stream_contexts[i].encoder == NULL) {
+ ASSERT(false);/*display path missing core components*/
+ return false;
+ }
+ }
+ /* verify signal support accross whole chain (however it is not a bug
+ * if not supported, just we shoudl skip this display path)*/
+ if (sink_signal == SIGNAL_TYPE_NONE)
+ return false;
+
+ if (dal_display_path_set_sink_signal(path, sink_signal))
+ path->valid = true;
+
+ return path->valid;
+}
+
+bool dal_display_path_add_link(
+ struct display_path *path,
+ struct encoder *encoder)
+{
+ if (path->number_of_links >= MAX_NUM_OF_LINKS_PER_PATH)
+ return false;
+
+ path->stream_contexts[path->number_of_links++].encoder = encoder;
+ return true;
+}
+
+bool dal_display_path_add_connector(
+ struct display_path *path,
+ struct connector *connector)
+{
+ ASSERT(path != NULL && connector != NULL);
+ path->connector = connector;
+ return true;
+}
+struct connector *dal_display_path_get_connector(struct display_path *path)
+{
+ return path->connector;
+}
+
+int32_t dal_display_path_acquire(struct display_path *path)
+{
+ ++path->acquired_counter;
+ return path->acquired_counter;
+}
+
+int32_t dal_display_path_get_ref_counter(const struct display_path *path)
+{
+ return path->acquired_counter;
+}
+
+bool dal_display_path_is_acquired(const struct display_path *path)
+{
+ /* if counter is greater than zero than path is acquired */
+ return (dal_display_path_get_ref_counter(path) > 0);
+}
+
+int32_t dal_display_path_release(struct display_path *path)
+{
+ --path->acquired_counter;
+ return path->acquired_counter;
+}
+
+void dal_display_path_release_resources(struct display_path *path)
+{
+ uint32_t i;
+
+ for (i = 0; i < path->number_of_links; i++) {
+ struct stream_context *cntx = &path->stream_contexts[i];
+
+ cntx->state.LINK = false;
+ cntx->state.AUDIO = false;
+ cntx->engine = ENGINE_ID_UNKNOWN;
+ cntx->input_config_signal = SIGNAL_TYPE_NONE;
+ cntx->output_config_signal = SIGNAL_TYPE_NONE;
+ cntx->link_config_interface = NULL;
+ }
+
+ path->clock_source = NULL;
+ path->alt_clock_source = NULL;
+ /* TODO: GL sync*/
+ path->stereo_sync_object = NULL;
+ path->sync_output_object = NULL;
+ path->sync_output_source = SYNC_SOURCE_NONE;
+ path->sync_input_source = SYNC_SOURCE_NONE;
+
+ dal_display_path_release_planes(path);
+}
+
+bool dal_display_path_is_source_blanked(const struct display_path *path)
+{
+ return path->src_tgt_state.src_blanked == DISPLAY_TRI_STATE_TRUE;
+}
+bool dal_display_path_is_source_unblanked(const struct display_path *path)
+{
+ return path->src_tgt_state.src_blanked == DISPLAY_TRI_STATE_FALSE;
+}
+void dal_display_path_set_source_blanked(
+ struct display_path *path,
+ enum display_tri_state state)
+{
+ path->src_tgt_state.src_blanked = state;
+}
+bool dal_display_path_is_target_blanked(const struct display_path *path)
+{
+ return path->src_tgt_state.tgt_blanked == DISPLAY_TRI_STATE_TRUE;
+}
+
+bool dal_display_path_is_target_unblanked(const struct display_path *path)
+{
+ return path->src_tgt_state.tgt_blanked == DISPLAY_TRI_STATE_FALSE;
+}
+void dal_display_path_set_target_blanked(
+ struct display_path *path,
+ enum display_tri_state state)
+{
+ path->src_tgt_state.tgt_blanked = state;
+}
+
+bool dal_display_path_is_target_powered_on(const struct display_path *path)
+{
+ return path->src_tgt_state.powered_on == DISPLAY_TRI_STATE_TRUE;
+}
+bool dal_display_path_is_target_powered_off(const struct display_path *path)
+{
+ return path->src_tgt_state.powered_on == DISPLAY_TRI_STATE_FALSE;
+}
+void dal_display_path_set_target_powered_on(
+ struct display_path *path,
+ enum display_tri_state state)
+{
+ path->src_tgt_state.powered_on = state;
+}
+
+bool dal_display_path_is_target_connected(const struct display_path *path)
+{
+ return path->connected;
+}
+
+void dal_display_path_set_target_connected(struct display_path *path, bool c)
+{
+ path->connected = c;
+}
+
+uint32_t dal_display_path_get_display_index(const struct display_path *path)
+{
+ return path->display_index;
+}
+void dal_display_path_set_display_index(
+ struct display_path *path,
+ uint32_t index)
+{
+ path->display_index = index;
+}
+
+struct connector_device_tag_info *dal_display_path_get_device_tag(
+ struct display_path *path)
+{
+ return &path->device_tag;
+}
+void dal_display_path_set_device_tag(
+ struct display_path *path,
+ struct connector_device_tag_info tag)
+{
+ ASSERT(tag.dev_id.device_type != DEVICE_TYPE_UNKNOWN);
+ path->device_tag = tag;
+}
+enum clock_sharing_group dal_display_path_get_clock_sharing_group(
+ const struct display_path *path)
+{
+ return path->clock_sharing_group;
+}
+void dal_display_path_set_clock_sharing_group(
+ struct display_path *path,
+ enum clock_sharing_group clock)
+{
+ path->clock_sharing_group = clock;
+}
+union display_path_properties dal_display_path_get_properties(
+ const struct display_path *path)
+{
+ return path->properties;
+}
+void dal_display_path_set_properties(
+ struct display_path *path,
+ union display_path_properties p)
+{
+ path->properties = p;
+}
+
+struct dcs *dal_display_path_get_dcs(const struct display_path *path)
+{
+ return path->dcs;
+}
+void dal_display_path_set_dcs(struct display_path *path, struct dcs *dcs)
+{
+ path->dcs = dcs;
+}
+
+uint32_t dal_display_path_get_number_of_links(const struct display_path *path)
+{
+ return path->number_of_links;
+}
+
+void dal_display_path_set_clock_source(
+ struct display_path *path,
+ struct clock_source *clock)
+{
+ path->clock_source = clock;
+}
+
+struct clock_source *dal_display_path_get_clock_source(
+ const struct display_path *path)
+{
+ return path->clock_source;
+}
+
+void dal_display_path_set_alt_clock_source(
+ struct display_path *path,
+ struct clock_source *clock)
+{
+ path->alt_clock_source = clock;
+}
+
+struct clock_source *dal_display_path_get_alt_clock_source(
+ const struct display_path *path)
+{
+ return path->alt_clock_source;
+}
+
+void dal_display_path_set_fbc_info(
+ struct display_path *path,
+ struct fbc_info *fbc_info)
+{
+ path->fbc_info = *fbc_info;
+}
+
+struct fbc_info *dal_display_path_get_fbc_info(struct display_path *path)
+{
+ return &path->fbc_info;
+}
+
+void dal_display_path_acquire_links(struct display_path *path)
+{
+ uint32_t i;
+
+ for (i = 0; i < path->number_of_links; i++) {
+ path->stream_contexts[i].input_config_signal =
+ path->stream_contexts[i].input_query_signal;
+ path->stream_contexts[i].output_config_signal =
+ path->stream_contexts[i].output_query_signal;
+ path->stream_contexts[i].link_config_interface =
+ path->stream_contexts[i].link_query_interface;
+ }
+}
+
+struct link_service *dal_display_path_get_mst_link_service(
+ const struct display_path *path)
+{
+ uint32_t i;
+ struct link_service *link_service = NULL;
+
+ for (i = 0; i < path->number_of_links; i++) {
+ link_service = path->stream_contexts[i].link_query_interface;
+ if (link_service != NULL
+ && dal_ls_get_link_service_type(link_service)
+ == LINK_SERVICE_TYPE_DP_MST) {
+ return link_service;
+ }
+ }
+
+ return NULL;
+}
+
+/* This function is for backward compatibility only (called from many places).
+ * (All callers are interested in the "root" controller)
+ * TODO: remove it when Planes code is finalised. */
+struct controller *dal_display_path_get_controller(
+ const struct display_path *path)
+{
+ struct display_path_plane *plane_zero =
+ dal_display_path_get_plane_at_index(path, 0);
+
+ /* In many places code expects/checks for NULL and acts accordingly.
+ * That means we should NOT use CRITICAL_ASSERT() here. */
+ if (NULL != plane_zero)
+ return plane_zero->controller;
+ else
+ return NULL;
+}
+
+void dal_display_path_set_sync_output_object(
+ struct display_path *path,
+ enum sync_source o_source,
+ struct encoder *o_object)
+{
+ /*Overwriting sync-output object*/
+ ASSERT(path->sync_output_object == NULL || o_object == NULL);
+ /*Overwriting sync-output source*/
+ ASSERT(path->sync_input_source == SYNC_SOURCE_NONE
+ || o_source == SYNC_SOURCE_NONE);
+
+ path->sync_output_source = o_source;
+ path->sync_output_object = o_object;
+}
+
+struct encoder *dal_display_path_get_sync_output_object(
+ const struct display_path *path)
+{
+ return path->sync_output_object;
+}
+
+void dal_display_path_set_stereo_sync_object(
+ struct display_path *path,
+ struct encoder *stereo_sync)
+{
+ path->stereo_sync_object = stereo_sync;
+}
+
+struct encoder *dal_display_path_get_stereo_sync_object(
+ const struct display_path *path)
+{
+ return path->stereo_sync_object;
+}
+
+void dal_display_path_set_sync_input_source(
+ struct display_path *path,
+ enum sync_source s)
+{
+ path->sync_input_source = s;
+}
+
+enum sync_source dal_display_path_get_sync_input_source(
+ const struct display_path *path)
+{
+ return path->sync_input_source;
+}
+
+void dal_display_path_set_sync_output_source(
+ struct display_path *path,
+ enum sync_source s)
+{
+ path->sync_output_source = s;
+}
+
+enum sync_source dal_display_path_get_sync_output_source(
+ const struct display_path *path)
+{
+ return path->sync_output_source;
+}
+
+bool dal_display_path_set_pixel_clock_safe_range(
+ struct display_path *path,
+ struct pixel_clock_safe_range *range)
+{
+ struct timing_limits timing_limits = { 0 };
+
+ if (range == NULL)
+ return false;
+
+ dal_dcs_get_timing_limits(path->dcs, &timing_limits);
+
+ if (range->min_frequency > range->max_frequency) {
+ /* minimum grater than maximum
+ * we can actually swap them and continue
+ * , but the caller should not rely on that*/
+ return false;
+ }
+
+ if (range->min_frequency < timing_limits.min_pixel_clock_in_khz
+ || range->max_frequency
+ > timing_limits.max_pixel_clock_in_khz) {
+ /* provided range is out of timing limits*/
+ return false;
+ }
+
+ path->pixel_clock_safe_range = *range;
+ return true;
+}
+bool dal_display_path_get_pixel_clock_safe_range(
+ const struct display_path *path,
+ struct pixel_clock_safe_range *range)
+{
+ if (range != NULL && path->pixel_clock_safe_range.max_frequency) {
+ *range = path->pixel_clock_safe_range;
+ return true;
+ }
+
+ return false;
+}
+
+void dal_display_path_set_drr_config(
+ struct display_path *path,
+ struct drr_config *drr_cfg)
+{
+ if (drr_cfg != NULL)
+ path->drr_cfg = *drr_cfg;
+ else
+ dal_memset(&path->drr_cfg, 0, sizeof(path->drr_cfg));
+}
+void dal_display_path_get_drr_config(
+ const struct display_path *path,
+ struct drr_config *drr_cfg)
+{
+ if (drr_cfg != NULL)
+ *drr_cfg = path->drr_cfg;
+}
+
+bool dal_display_path_set_sink_signal(
+ struct display_path *path,
+ enum signal_type sink_signal)
+{
+ int32_t i;
+ enum signal_type current_signal;
+
+ /* for hdmi connector, we want to ensure that
+ * the display path supports hdmi*/
+ if ((sink_signal == SIGNAL_TYPE_HDMI_TYPE_A)
+ && !path->properties.bits.IS_HDMI_AUDIO_SUPPORTED) {
+ ASSERT(false);/*HDMI audio not supported on this display path*/
+ return false;
+ }
+
+ if (calculate_asic_signal(path, sink_signal) == SIGNAL_TYPE_NONE) {
+ ASSERT(false);/* Failed to set requested signal */
+ return false;
+ }
+
+ current_signal = sink_signal;
+ for (i = path->number_of_links - 1; i >= 0; --i) {
+ path->stream_contexts[i].output_query_signal =
+ current_signal;
+ current_signal = calculate_upstream_signal(path, current_signal,
+ i);
+ path->stream_contexts[i].input_query_signal = current_signal;
+ }
+ return true;
+
+}
+
+enum signal_type dal_display_path_sink_signal_to_asic_signal(
+ struct display_path *path,
+ enum signal_type sink_signal)
+{
+ return calculate_asic_signal(path, sink_signal);
+}
+enum signal_type dal_display_path_sink_signal_to_link_signal(
+ struct display_path *path,
+ enum signal_type sink_signal,
+ uint32_t idx)
+{
+ enum signal_type current_signal = sink_signal;
+ int32_t i;
+
+ if (path->connector == NULL)
+ return SIGNAL_TYPE_NONE;
+ if ((dal_connector_enumerate_output_signals(path->connector)
+ & sink_signal) == 0) {
+ return SIGNAL_TYPE_NONE;
+ }
+
+ for (i = path->number_of_links - 1; i >= 0; --i) {
+ if (idx == i)
+ return current_signal;
+
+ current_signal = calculate_upstream_signal(path, current_signal,
+ i);
+ }
+
+ return current_signal;
+}
+
+enum signal_type dal_display_path_downstream_to_upstream_signal(
+ struct display_path *path,
+ enum signal_type signal,
+ uint32_t idx)
+{
+ return calculate_upstream_signal(path, signal, idx);
+}
+
+bool dal_display_path_is_ss_supported(const struct display_path *path)
+{
+ return is_ss_forced_enable(path) ? true : path->ss_supported;
+}
+bool dal_display_path_is_ss_configurable(const struct display_path *path)
+{
+ return !is_ss_forced_enable(path);
+}
+void dal_display_path_set_ss_support(struct display_path *path, bool s)
+{
+ path->ss_supported = s;
+}
+
+void dal_display_path_set_static_screen_triggers(
+ struct display_path *path,
+ const struct static_screen_events *events)
+{
+ if (events != NULL)
+ path->static_screen_config.u_all = events->u_all;
+ else
+ path->static_screen_config.u_all = 0;
+}
+void dal_display_path_get_static_screen_triggers(
+ const struct display_path *path,
+ struct static_screen_events *events)
+{
+ if (events != NULL)
+ events->u_all = path->static_screen_config.u_all;
+}
+
+bool dal_display_path_is_psr_supported(const struct display_path *path)
+{
+ return false;
+}
+
+bool dal_display_path_is_drr_supported(const struct display_path *path)
+{
+ struct link_service *ls =
+ dal_display_path_get_link_query_interface(
+ path, SINK_LINK_INDEX);
+ struct drr_config drr_config;
+
+ dal_display_path_get_drr_config(path, &drr_config);
+
+ /* The check for DRR supported returns true means it satisfied:
+ * 1. EDID reported DRR capability and Stream supports DRR or
+ * 2. Forced capability through runtime parameter or
+ * 3. Forced capability through VBIOS */
+ if (((drr_config.support_method.SUPPORTED_BY_EDID == 1) &&
+ dal_ls_is_stream_drr_supported(ls)) ||
+ (drr_config.support_method.FORCED_BY_REGKEY_OR_ESCAPE == 1) ||
+ (drr_config.support_method.FORCED_BY_VBIOS == 1))
+ return true;
+ return false;
+}
+
+void dal_display_path_set_link_service_data(
+ struct display_path *path,
+ uint32_t idx,
+ const struct goc_link_service_data *data)
+{
+
+ if (idx < path->number_of_links && data != NULL)
+ path->stream_contexts[idx].link_service_data = *data;
+}
+bool dal_display_path_get_link_service_data(
+ const struct display_path *path,
+ uint32_t idx,
+ struct goc_link_service_data *data)
+{
+ if (idx < path->number_of_links && data != NULL) {
+ *data = path->stream_contexts[idx].link_service_data;
+ return true;
+ }
+ return false;
+}
+
+bool dal_display_path_is_audio_present(
+ const struct display_path *path,
+ uint32_t *audio_pin)
+{
+ uint32_t i;
+ const struct stream_context *link;
+ struct audio_feature_support features;
+
+ for (i = 0; i < path->number_of_links; i++) {
+ link = &path->stream_contexts[i];
+
+ if (!link->state.AUDIO)
+ continue;
+ if (link->audio == NULL)
+ continue;
+ features = dal_audio_get_supported_features(link->audio);
+ /*For DCE6.x and higher*/
+ if (features.MULTISTREAM_AUDIO && audio_pin != NULL)
+ *audio_pin = dal_audio_get_graphics_object_id(
+ link->audio).enum_id - 1;
+ return true;
+ }
+ return false;
+}
+
+bool dal_display_path_is_dp_auth_supported(struct display_path *path)
+{
+ uint32_t i;
+ struct encoder_feature_support features;
+ struct stream_context *link;
+
+ for (i = 0; i < path->number_of_links; i++) {
+ link = &path->stream_contexts[i];
+ features = dal_encoder_get_supported_features(link->encoder);
+
+ if (link->state.LINK
+ && features.flags.bits.CPLIB_DP_AUTHENTICATION)
+ return true;
+ }
+ return false;
+
+}
+bool dal_display_path_is_vce_supported(const struct display_path *path)
+{
+ uint32_t i;
+ const struct stream_context *link;
+ struct encoder_feature_support features;
+
+ for (i = 0; i < path->number_of_links; i++) {
+ link = &path->stream_contexts[i];
+ features = dal_encoder_get_supported_features(link->encoder);
+ if (features.flags.bits.IS_VCE_SUPPORTED)
+ return true;
+ }
+ return false;
+}
+bool dal_display_path_is_sls_capable(const struct display_path *path)
+{
+ switch (dal_display_path_get_query_signal(path, SINK_LINK_INDEX)) {
+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
+ case SIGNAL_TYPE_DVI_SINGLE_LINK1:
+ case SIGNAL_TYPE_DVI_DUAL_LINK:
+ case SIGNAL_TYPE_HDMI_TYPE_A:
+ case SIGNAL_TYPE_LVDS:
+ case SIGNAL_TYPE_RGB:
+ case SIGNAL_TYPE_DISPLAY_PORT:
+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
+ case SIGNAL_TYPE_EDP:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+bool dal_display_path_is_gen_lock_capable(const struct display_path *path)
+{
+ switch (dal_display_path_get_query_signal(path, SINK_LINK_INDEX)) {
+ case SIGNAL_TYPE_DVI_SINGLE_LINK:
+ case SIGNAL_TYPE_DVI_SINGLE_LINK1:
+ case SIGNAL_TYPE_DVI_DUAL_LINK:
+ case SIGNAL_TYPE_HDMI_TYPE_A:
+ case SIGNAL_TYPE_DISPLAY_PORT:
+ case SIGNAL_TYPE_DISPLAY_PORT_MST:
+ case SIGNAL_TYPE_EDP:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+struct transmitter_configuration dal_display_path_get_transmitter_configuration(
+ const struct display_path *path,
+ bool physical)
+{
+ struct encoder *encoder = NULL;
+ int32_t i;
+ struct transmitter_configuration config = { { .transmitter_phy_id =
+ TRANSMITTER_UNKNOWN, .output_channel_mapping.raw =
+ INVALID_DDI_CHANNEL_MAPPING }, { .transmitter_phy_id =
+ TRANSMITTER_UNKNOWN, .output_channel_mapping.raw =
+ INVALID_DDI_CHANNEL_MAPPING } };
+
+ /* Find last internal encoder*/
+ for (i = path->number_of_links - 1; i >= 0; --i) {
+ encoder = path->stream_contexts[i].encoder;
+ if (!dal_encoder_get_supported_features(
+ encoder).flags.bits.EXTERNAL_ENCODER)
+ break;
+
+ encoder = NULL;
+ }
+
+ if (encoder == NULL)
+ return config;
+
+ /* Fetch mapping for primary transmitter*/
+ if (physical)
+ /* this is for SMU per PCIe lane power gating */
+ config.primary_transmitter_config.transmitter_phy_id =
+ dal_encoder_get_phy(encoder);
+ else
+ /* this is for CPlib HW register r/w */
+ config.primary_transmitter_config.transmitter_phy_id =
+ dal_encoder_get_transmitter(encoder);
+
+ if (config.primary_transmitter_config.transmitter_phy_id
+ != TRANSMITTER_UNKNOWN)
+ config.primary_transmitter_config.output_channel_mapping =
+ path->ddi_channel_mapping;
+
+ /* Fetch mapping for secondary transmitter*/
+ switch (dal_display_path_get_query_signal(path, ASIC_LINK_INDEX)) {
+ case SIGNAL_TYPE_DVI_DUAL_LINK:
+ if (physical)
+ config.secondary_transmitter_config.transmitter_phy_id =
+ dal_encoder_get_paired_phy(encoder);
+ else
+ config.secondary_transmitter_config.transmitter_phy_id =
+ dal_encoder_get_paired_transmitter(encoder);
+
+ config.secondary_transmitter_config.output_channel_mapping =
+ path->ddi_channel_mapping;
+ break;
+
+ default:
+ break;
+ }
+
+ return config;
+
+}
+enum signal_type dal_display_path_get_active_signal(
+ struct display_path *path,
+ uint32_t idx)
+{
+ if (dal_display_path_is_acquired(path))
+ return dal_display_path_get_config_signal(path, idx);
+ else
+ return dal_display_path_get_query_signal(path, idx);
+}
+
+void dal_display_path_set_ddi_channel_mapping(
+ struct display_path *path,
+ union ddi_channel_mapping mapping)
+{
+ path->ddi_channel_mapping = mapping;
+}
+
+bool dal_display_path_contains_object(
+ struct display_path *path,
+ struct graphics_object_id id)
+{
+ struct graphics_object_id path_obj;
+ uint32_t i;
+ /* 1. Check Connector*/
+ if (path->connector != NULL) {
+ path_obj = dal_connector_get_graphics_object_id(
+ path->connector);
+ if (dal_graphics_object_id_is_equal(path_obj, id))
+ return true;
+ }
+
+ /* 2. Check link components*/
+ for (i = 0; i < path->number_of_links; i++) {
+ if (path->stream_contexts[i].encoder != NULL) {
+ path_obj = dal_encoder_get_graphics_object_id(
+ path->stream_contexts[i].encoder);
+ if (dal_graphics_object_id_is_equal(path_obj, id))
+ return true;
+ }
+
+ if (path->stream_contexts[i].audio != NULL) {
+ path_obj = dal_audio_get_graphics_object_id(
+ path->stream_contexts[i].audio);
+ if (dal_graphics_object_id_is_equal(path_obj, id))
+ return true;
+ }
+ }
+
+ /* 3. Check DCP mandatory components*/
+ if (path->clock_source != NULL) {
+ path_obj = dal_clock_source_get_graphics_object_id(
+ path->clock_source);
+ if (dal_graphics_object_id_is_equal(path_obj, id))
+ return true;
+ }
+
+ if (path->alt_clock_source != NULL) {
+ path_obj = dal_clock_source_get_graphics_object_id(
+ path->alt_clock_source);
+ if (dal_graphics_object_id_is_equal(path_obj, id))
+ return true;
+ }
+
+ {
+ uint8_t planes_no = dal_display_path_get_number_of_planes(path);
+ uint8_t i;
+ struct controller *controller;
+
+ for (i = 0; i < planes_no; i++) {
+ controller =
+ dal_display_path_get_controller_for_layer_index(
+ path, i);
+
+ path_obj = dal_controller_get_graphics_object_id(
+ controller);
+
+ if (dal_graphics_object_id_is_equal(path_obj, id))
+ return true;
+ }
+ }
+
+ if (path->stereo_sync_object != NULL) {
+ path_obj = dal_encoder_get_graphics_object_id(
+ path->stereo_sync_object);
+ if (dal_graphics_object_id_is_equal(path_obj, id))
+ return true;
+ }
+
+ if (path->sync_output_object != NULL) {
+ path_obj = dal_encoder_get_graphics_object_id(
+ path->sync_output_object);
+ if (dal_graphics_object_id_is_equal(path_obj, id))
+ return true;
+ }
+
+ /*
+ * TODO:Add GLSync here
+ */
+ return false;
+}
+
+/********************
+ * Multi-plane code
+ ********************/
+
+bool dal_display_path_add_plane(
+ struct display_path *path,
+ struct display_path_plane *plane)
+{
+ if (false == display_path_plane_vector_append(
+ path->planes,
+ plane)) {
+ /* TODO: add a debug message here */
+ return false;
+ }
+
+ /* this is the case when root controller added */
+ if (dal_vector_get_count(path->planes) == 1)
+ path->src_tgt_state.src_blanked = DISPLAY_TRI_STATE_UNKNOWN;
+
+ return true;
+}
+
+uint8_t dal_display_path_get_number_of_planes(
+ const struct display_path *path)
+{
+ return dal_vector_get_count(path->planes);
+}
+
+struct display_path_plane *dal_display_path_get_plane_at_index(
+ const struct display_path *path,
+ uint8_t index)
+{
+ return display_path_plane_vector_at_index(path->planes, index);
+}
+
+struct controller *dal_display_path_get_controller_for_layer_index(
+ const struct display_path *path,
+ uint8_t layer_index)
+{
+ struct display_path_plane *plane;
+
+ /* the planes are ordered starting from zero */
+ plane = dal_display_path_get_plane_at_index(path, layer_index);
+ if (!plane) {
+ /* Not found. TODO: add a debug message here. */
+ return NULL;
+ }
+
+ return plane->controller;
+}
+
+void dal_display_path_release_planes(
+ struct display_path *path)
+{
+ dal_vector_clear(path->planes);
+}
+
+void dal_display_path_release_non_root_planes(
+ struct display_path *path)
+{
+ uint32_t last_plane = dal_vector_get_count(path->planes) - 1;
+
+ for (; last_plane > 0; last_plane--)
+ dal_vector_remove_at_index(path->planes, last_plane);
+}
+/********************
+ * End-of-Multi-plane code
+ ********************/
diff --git a/drivers/gpu/drm/amd/dal/display_path/display_path.h b/drivers/gpu/drm/amd/dal/display_path/display_path.h
new file mode 100644
index 000000000000..088d662132e1
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/display_path/display_path.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DISPLAY_PATH_H__
+#define __DISPLAY_PATH_H__
+
+struct stream_context {
+ struct active_state {
+ bool LINK:1; /* if link is active, encoder always active*/
+ bool AUDIO:1;
+ } state;
+ /* same on all streams on shared link*/
+ struct encoder *encoder;
+ struct link_service *link_query_interface;
+ struct link_service *link_config_interface;
+ /* distinct objects for each stream*/
+ struct audio *audio;
+ enum engine_id engine;
+
+ enum signal_type input_query_signal;
+ enum signal_type output_query_signal;
+ enum signal_type input_config_signal;
+ enum signal_type output_config_signal;
+ /* temporary - eventually will move to link service*/
+ struct goc_link_service_data link_service_data;
+};
+
+struct display_path {
+
+ /*struct stream_context stream_contexts[MAX_NUM_OF_LINKS_PER_PATH];*/
+ /*uint32_t number_of_links;*/
+ struct stream_context stream_contexts[MAX_NUM_OF_LINKS_PER_PATH];
+ uint32_t number_of_links;
+ struct connector *connector;
+
+ /* dcp components that attached only on acquired display path*/
+ struct clock_source *clock_source;
+
+ /* optional components that attached only on acquired display path*/
+ /*struct glsync_connector *gl_sync_object;*/
+ struct encoder *stereo_sync_object;
+ /* always set when sync-output attached*/
+ enum sync_source sync_output_source;
+ /* optional complement to sync_output_source, can be null*/
+ struct encoder *sync_output_object;
+
+ enum sync_source sync_input_source;
+ /* optional, alternative clk src for dpref signal*/
+ struct clock_source *alt_clock_source;
+
+ struct dcs *dcs;
+
+ /* state*/
+ struct src_tgt_state {
+ /* display path enabled in hwss terminology*/
+ enum display_tri_state powered_on;
+ /* display path blanked, nothing to do with crtc blank*/
+ enum display_tri_state tgt_blanked;
+ /* display path blanked, nothing to do with crtc blank*/
+ enum display_tri_state src_blanked;
+ } src_tgt_state;
+
+ bool connected; /* display connected*/
+ int32_t acquired_counter; /* if zero then Path is not acquired by
+ a "HW" method */
+ bool valid;
+
+ /* properties*/
+ union display_path_properties properties;
+ struct connector_device_tag_info device_tag;
+ uint32_t display_index;
+ enum clock_sharing_group clock_sharing_group;
+
+ /* features*/
+ struct fbc_info fbc_info;
+ bool ss_supported;
+ struct pixel_clock_safe_range pixel_clock_safe_range;
+ union ddi_channel_mapping ddi_channel_mapping;
+ struct drr_config drr_cfg;
+ struct static_screen_events static_screen_config;
+
+ /* Multi-Plane components */
+ /* Each path will have at least one Plane. It could be driven
+ * by a Primary or an Underlay pipe. */
+ struct vector *planes;
+};
+
+#endif /* __DISPLAY_PATH_H__ */
diff --git a/drivers/gpu/drm/amd/dal/display_path/stream_context.c b/drivers/gpu/drm/amd/dal/display_path/stream_context.c
new file mode 100644
index 000000000000..95b71c9a2890
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/display_path/stream_context.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dal_services.h"
+
+#include "include/display_path_interface.h"
+#include "display_path.h"
+
+struct link_service *dal_display_path_get_link_query_interface(
+ const struct display_path *path, uint32_t idx)
+{
+
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ return path->stream_contexts[idx].link_query_interface;
+ return NULL;
+}
+void dal_display_path_set_link_query_interface(struct display_path *path,
+ uint32_t idx, struct link_service *link)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ path->stream_contexts[idx].link_query_interface = link;
+}
+struct link_service *dal_display_path_get_link_config_interface(
+ const struct display_path *path, uint32_t idx)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ return path->stream_contexts[idx].link_config_interface;
+ return NULL;
+}
+struct link_service *dal_display_path_get_link_service_interface(
+ const struct display_path *path, uint32_t idx)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ return path->stream_contexts[idx].link_query_interface;
+ return NULL;
+}
+
+struct encoder *dal_display_path_get_upstream_encoder(
+ const struct display_path *path, uint32_t idx)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links
+ && path->stream_contexts[idx].state.LINK)
+ return path->stream_contexts[idx].encoder;
+ return NULL;
+}
+struct encoder *dal_display_path_get_upstream_object(
+ const struct display_path *path, uint32_t idx)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ return path->stream_contexts[idx].encoder;
+ return NULL;
+}
+struct encoder *dal_display_path_get_downstream_encoder(
+ const struct display_path *path, uint32_t idx)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx + 1 < path->number_of_links
+ && path->stream_contexts[idx].state.LINK)
+ return path->stream_contexts[idx + 1].encoder;
+ return NULL;
+}
+struct encoder *dal_display_path_get_downstream_object(
+ const struct display_path *path, uint32_t idx)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx + 1 < path->number_of_links)
+ return path->stream_contexts[idx + 1].encoder;
+ return NULL;
+
+}
+
+struct audio *dal_display_path_get_audio(const struct display_path *path,
+ uint32_t idx)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links
+ && path->stream_contexts[idx].state.AUDIO)
+ return path->stream_contexts[idx].audio;
+ return NULL;
+}
+void dal_display_path_set_audio(struct display_path *path, uint32_t idx,
+ struct audio *a)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ path->stream_contexts[idx].audio = a;
+}
+struct audio *dal_display_path_get_audio_object(
+ const struct display_path *path, uint32_t idx)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ return path->stream_contexts[idx].audio;
+ return NULL;
+}
+void dal_display_path_set_audio_active_state(struct display_path *path,
+ uint32_t idx, bool state)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ path->stream_contexts[idx].state.AUDIO = state;
+}
+
+enum engine_id dal_display_path_get_stream_engine(
+ const struct display_path *path, uint32_t idx)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ return path->stream_contexts[idx].engine;
+ return ENGINE_ID_UNKNOWN;
+}
+void dal_display_path_set_stream_engine(struct display_path *path, uint32_t idx,
+ enum engine_id id)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ path->stream_contexts[idx].engine = id;
+}
+
+bool dal_display_path_is_link_active(const struct display_path *path,
+ uint32_t idx)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ return path->stream_contexts[idx].state.LINK;
+ return false;
+
+}
+void dal_display_path_set_link_active_state(struct display_path *path,
+ uint32_t idx, bool state)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ path->stream_contexts[idx].state.LINK = state;
+}
+
+enum signal_type dal_display_path_get_config_signal(
+ const struct display_path *path, uint32_t idx)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ return path->stream_contexts[idx].output_config_signal;
+ return SIGNAL_TYPE_NONE;
+
+}
+enum signal_type dal_display_path_get_query_signal(
+ const struct display_path *path, uint32_t idx)
+{
+ idx = (idx == SINK_LINK_INDEX) ? path->number_of_links - 1 : idx;
+ if (idx < path->number_of_links)
+ return path->stream_contexts[idx].output_query_signal;
+ return SIGNAL_TYPE_NONE;
+}
diff --git a/drivers/gpu/drm/amd/dal/include/display_path_interface.h b/drivers/gpu/drm/amd/dal/include/display_path_interface.h
new file mode 100644
index 000000000000..7bf2ef28f455
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/include/display_path_interface.h
@@ -0,0 +1,436 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DISPLAY_PATH_INTERFACE_H__
+#define __DISPLAY_PATH_INTERFACE_H__
+
+#include "display_path_types.h"
+#include "dcs_types.h"
+#include "grph_object_ctrl_defs.h"
+#include "signal_types.h"
+#include "controller_types.h"
+
+struct encoder;
+struct controller;
+struct connector;
+struct audio;
+struct clock_source;
+struct link_service;
+struct goc_link_service_data;
+struct drr_config;
+
+struct display_path;
+
+struct display_path *dal_display_path_create(void);
+
+struct display_path *dal_display_path_clone(
+ const struct display_path *self,
+ bool copy_active_state);
+
+void dal_display_path_destroy(
+ struct display_path **to_destroy);
+
+bool dal_display_path_validate(
+ struct display_path *path,
+ enum signal_type sink_signal);
+
+bool dal_display_path_add_link(
+ struct display_path *path,
+ struct encoder *encoder);
+
+bool dal_display_path_add_connector(
+ struct display_path *path,
+ struct connector *connector);
+
+struct connector *dal_display_path_get_connector(
+ struct display_path *path);
+
+int32_t dal_display_path_acquire(
+ struct display_path *path);
+
+bool dal_display_path_is_acquired(
+ const struct display_path *path);
+
+int32_t dal_display_path_get_ref_counter(
+ const struct display_path *path);
+
+int32_t dal_display_path_release(
+ struct display_path *path);
+
+void dal_display_path_release_resources(
+ struct display_path *path);
+
+void dal_display_path_acquire_links(
+ struct display_path *path);
+
+bool dal_display_path_is_source_blanked(
+ const struct display_path *path);
+
+bool dal_display_path_is_source_unblanked(
+ const struct display_path *path);
+
+void dal_display_path_set_source_blanked(
+ struct display_path *path,
+ enum display_tri_state state);
+
+bool dal_display_path_is_target_blanked(
+ const struct display_path *path);
+
+bool dal_display_path_is_target_unblanked(
+ const struct display_path *path);
+
+void dal_display_path_set_target_blanked(
+ struct display_path *path,
+ enum display_tri_state state);
+
+bool dal_display_path_is_target_powered_on(
+ const struct display_path *path);
+
+bool dal_display_path_is_target_powered_off(
+ const struct display_path *path);
+
+void dal_display_path_set_target_powered_on(
+ struct display_path *path,
+ enum display_tri_state state);
+
+bool dal_display_path_is_target_connected(
+ const struct display_path *path);
+
+void dal_display_path_set_target_connected(
+ struct display_path *path,
+ bool c);
+
+uint32_t dal_display_path_get_display_index(
+ const struct display_path *path);
+
+void dal_display_path_set_display_index(
+ struct display_path *path,
+ uint32_t index);
+
+struct connector_device_tag_info *dal_display_path_get_device_tag(
+ struct display_path *path);
+
+void dal_display_path_set_device_tag(
+ struct display_path *path,
+ struct connector_device_tag_info tag);
+
+enum clock_sharing_group dal_display_path_get_clock_sharing_group(
+ const struct display_path *path);
+
+void dal_display_path_set_clock_sharing_group(
+ struct display_path *path,
+ enum clock_sharing_group clock);
+
+union display_path_properties dal_display_path_get_properties(
+ const struct display_path *path);
+
+void dal_display_path_set_properties(
+ struct display_path *path,
+ union display_path_properties p);
+
+struct dcs *dal_display_path_get_dcs(
+ const struct display_path *path);
+
+void dal_display_path_set_dcs(
+ struct display_path *path,
+ struct dcs *dcs);
+
+uint32_t dal_display_path_get_number_of_links(
+ const struct display_path *path);
+
+void dal_display_path_set_controller(
+ struct display_path *path,
+ struct controller *controller);
+
+struct controller *dal_display_path_get_controller(
+ const struct display_path *path);
+
+void dal_display_path_set_clock_source(
+ struct display_path *path,
+ struct clock_source *clock);
+
+struct clock_source *dal_display_path_get_clock_source(
+ const struct display_path *path);
+
+void dal_display_path_set_alt_clock_source(
+ struct display_path *path,
+ struct clock_source *clock);
+
+struct clock_source *dal_display_path_get_alt_clock_source(
+ const struct display_path *path);
+
+void dal_display_path_set_fbc_info(
+ struct display_path *path,
+ struct fbc_info *clock);
+
+struct fbc_info *dal_display_path_get_fbc_info(
+ struct display_path *path);
+
+void dal_display_path_set_drr_config(
+ struct display_path *path,
+ struct drr_config *clock);
+
+void dal_display_path_get_drr_config(
+ const struct display_path *path,
+ struct drr_config *clock);
+
+void dal_display_path_set_static_screen_triggers(
+ struct display_path *path,
+ const struct static_screen_events *events);
+
+void dal_display_path_get_static_screen_triggers(
+ const struct display_path *path,
+ struct static_screen_events *events);
+
+bool dal_display_path_is_psr_supported(
+ const struct display_path *path);
+
+bool dal_display_path_is_drr_supported(
+ const struct display_path *path);
+
+void dal_display_path_set_link_service_data(
+ struct display_path *path,
+ uint32_t idx,
+ const struct goc_link_service_data *data);
+
+bool dal_display_path_get_link_service_data(
+ const struct display_path *path,
+ uint32_t idx,
+ struct goc_link_service_data *data);
+
+struct link_service *dal_display_path_get_link_query_interface(
+ const struct display_path *path,
+ uint32_t idx);
+
+void dal_display_path_set_link_query_interface(
+ struct display_path *path,
+ uint32_t idx,
+ struct link_service *link);
+
+struct link_service *dal_display_path_get_link_config_interface(
+ const struct display_path *path,
+ uint32_t idx);
+
+struct link_service *dal_display_path_get_link_service_interface(
+ const struct display_path *path,
+ uint32_t idx);
+
+struct encoder *dal_display_path_get_upstream_encoder(
+ const struct display_path *path,
+ uint32_t idx);
+
+struct encoder *dal_display_path_get_upstream_object(
+ const struct display_path *path,
+ uint32_t idx);
+
+struct encoder *dal_display_path_get_downstream_encoder(
+ const struct display_path *path,
+ uint32_t idx);
+
+struct encoder *dal_display_path_get_downstream_object(
+ const struct display_path *path,
+ uint32_t idx);
+
+struct audio *dal_display_path_get_audio(
+ const struct display_path *path,
+ uint32_t idx);
+
+void dal_display_path_set_audio(
+ struct display_path *path,
+ uint32_t idx,
+ struct audio *a);
+
+struct audio *dal_display_path_get_audio_object(
+ const struct display_path *path,
+ uint32_t idx);
+
+void dal_display_path_set_audio_active_state(
+ struct display_path *path,
+ uint32_t idx,
+ bool state);
+
+enum engine_id dal_display_path_get_stream_engine(
+ const struct display_path *path,
+ uint32_t idx);
+
+void dal_display_path_set_stream_engine(
+ struct display_path *path,
+ uint32_t idx,
+ enum engine_id id);
+
+bool dal_display_path_is_link_active(
+ const struct display_path *path,
+ uint32_t idx);
+
+void dal_display_path_set_link_active_state(
+ struct display_path *path,
+ uint32_t idx,
+ bool state);
+
+enum signal_type dal_display_path_get_config_signal(
+ const struct display_path *path,
+ uint32_t idx);
+
+enum signal_type dal_display_path_get_query_signal(
+ const struct display_path *path,
+ uint32_t idx);
+
+struct link_service *dal_display_path_get_mst_link_service(
+ const struct display_path *path);
+
+void dal_display_path_set_sync_output_object(
+ struct display_path *path,
+ enum sync_source o_source,
+ struct encoder *o_object);
+
+struct encoder *dal_display_path_get_sync_output_object(
+ const struct display_path *path);
+
+void dal_display_path_set_stereo_sync_object(
+ struct display_path *path,
+ struct encoder *stereo_sync);
+
+struct encoder *dal_display_path_get_stereo_sync_object(
+ const struct display_path *path);
+
+void dal_display_path_set_sync_input_source(
+ struct display_path *path,
+ enum sync_source s);
+
+enum sync_source dal_display_path_get_sync_input_source(
+ const struct display_path *path);
+
+void dal_display_path_set_sync_output_source(
+ struct display_path *path,
+ enum sync_source s);
+
+enum sync_source dal_display_path_get_sync_output_source(
+ const struct display_path *path);
+
+bool dal_display_path_set_pixel_clock_safe_range(
+ struct display_path *path,
+ struct pixel_clock_safe_range *range);
+
+bool dal_display_path_get_pixel_clock_safe_range(
+ const struct display_path *path,
+ struct pixel_clock_safe_range *range);
+
+void dal_display_path_set_ddi_channel_mapping(
+ struct display_path *path,
+ union ddi_channel_mapping mapping);
+
+bool dal_display_path_set_sink_signal(
+ struct display_path *path,
+ enum signal_type sink_signal);
+
+enum signal_type dal_display_path_sink_signal_to_asic_signal(
+ struct display_path *path,
+ enum signal_type sink_signal);
+
+enum signal_type dal_display_path_sink_signal_to_link_signal(
+ struct display_path *path,
+ enum signal_type sink_signal,
+ uint32_t idx);
+
+enum signal_type dal_display_path_downstream_to_upstream_signal(
+ struct display_path *path,
+ enum signal_type signal,
+ uint32_t idx);
+
+bool dal_display_path_is_audio_present(
+ const struct display_path *path,
+ uint32_t *audio_pin);
+
+bool dal_display_path_is_dp_auth_supported(
+ struct display_path *path);
+
+bool dal_display_path_is_vce_supported(
+ const struct display_path *path);
+
+bool dal_display_path_is_sls_capable(
+ const struct display_path *path);
+
+bool dal_display_path_is_gen_lock_capable(
+ const struct display_path *path);
+
+struct transmitter_configuration dal_display_path_get_transmitter_configuration(
+ const struct display_path *path,
+ bool physical);
+
+bool dal_display_path_is_ss_supported(
+ const struct display_path *path);
+
+bool dal_display_path_is_ss_configurable(
+ const struct display_path *path);
+
+void dal_display_path_set_ss_support(
+ struct display_path *path,
+ bool s);
+
+enum signal_type dal_display_path_get_active_signal(
+ struct display_path *path,
+ uint32_t idx);
+
+bool dal_display_path_contains_object(
+ struct display_path *path,
+ struct graphics_object_id id);
+
+/* Multi-plane declarations.
+ * This structure should also be used for Stereo. */
+struct display_path_plane {
+ struct controller *controller;
+ /* During dal_tm_acquire_plane_resources() set blnd_mode, because
+ * "layer index" is known at that point, and we must decide how
+ * "controller" should do the blending */
+ enum blender_mode blnd_mode;
+ /* Some use-cases allow to power-gate FE.
+ * For example, with Full Screen Video on Underlay we can
+ * disable the 'root' plane.
+ * This flag indicates that FE should be power-gated */
+ bool disabled;
+};
+
+bool dal_display_path_add_plane(
+ struct display_path *path,
+ struct display_path_plane *plane);
+
+uint8_t dal_display_path_get_number_of_planes(
+ const struct display_path *path);
+
+struct display_path_plane *dal_display_path_get_plane_at_index(
+ const struct display_path *path,
+ uint8_t index);
+
+struct controller *dal_display_path_get_controller_for_layer_index(
+ const struct display_path *path,
+ uint8_t layer_index);
+
+void dal_display_path_release_planes(
+ struct display_path *path);
+
+void dal_display_path_release_non_root_planes(
+ struct display_path *path);
+
+#endif /* __DISPLAY_PATH_INTERFACE_H__ */
diff --git a/drivers/gpu/drm/amd/dal/include/display_path_types.h b/drivers/gpu/drm/amd/dal/include/display_path_types.h
new file mode 100644
index 000000000000..8aac46d50c76
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/include/display_path_types.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_DISPLAY_PATH_TYPES_H__
+#define __DAL_DISPLAY_PATH_TYPES_H__
+
+#include "grph_object_defs.h"
+
+enum {
+ CONTROLLER_HANDLE_INVALID = (uint32_t) (-1)
+};
+
+/*Limit maximum number of cofunctional paths*/
+enum {
+ MAX_COFUNCTIONAL_PATHS = 6
+};
+
+struct pixel_clock_safe_range {
+ uint32_t min_frequency;
+ uint32_t max_frequency;
+};
+
+/**
+ * ClockSharingGroup
+ * Enumeration of Clock Source Sharing categories
+ * Instead using enum we define valid range for clock sharing group values
+ * This is because potential num of group can be pretty big
+ */
+
+enum clock_sharing_group {
+ /* Default group for display paths that cannot share clock source.
+ * Display path in such group will aqcuire clock source exclusively*/
+ CLOCK_SHARING_GROUP_EXCLUSIVE = 0,
+ /* DisplayPort paths will have this group if clock sharing
+ * level is DisplayPortShareable*/
+ CLOCK_SHARING_GROUP_DISPLAY_PORT = 1,
+ /* Mst paths will have this group if clock sharing
+ * level is DpMstShareable*/
+ CLOCK_SHARING_GROUP_DP_MST = 2,
+ /* Display paths will have this group when
+ * desired to use alternative DPRef clock source.*/
+ CLOCK_SHARING_GROUP_ALTERNATIVE_DP_REF = 3,
+ /* Start of generic SW sharing groups.*/
+ CLOCK_SHARING_GROUP_GROUP1 = 4,
+ /* Total number of clock sharing groups.*/
+ CLOCK_SHARING_GROUP_MAX = 32,
+};
+/* Should be around maximal number of ever connected displays (since boot :)*/
+/*TEMP*/
+enum goc_link_settings_type {
+ GOC_LINK_SETTINGS_TYPE_PREFERRED = 0,
+ GOC_LINK_SETTINGS_TYPE_REPORTED,
+ GOC_LINK_SETTINGS_TYPE_TRAINED,
+ GOC_LINK_SETTINGS_TYPE_OVERRIDEN_TRAINED,
+ GOC_LINK_SETTINGS_TYPE_MAX
+};
+
+struct dp_audio_test_data {
+
+ struct dp_audio_test_data_flags {
+ uint32_t test_requested:1;
+ uint32_t disable_video:1;
+ } flags;
+
+ /*struct dp_audio_test_data_flags flags;*/
+ uint32_t sampling_rate;
+ uint32_t channel_count;
+ uint32_t pattern_type;
+ uint8_t pattern_period[8];
+};
+
+struct goc_link_service_data {
+ struct dp_audio_test_data dp_audio_test_data;
+};
+/* END-OF-TEMP*/
+
+
+union display_path_properties {
+ struct bit_map {
+ uint32_t ALWAYS_CONNECTED:1;
+ uint32_t HPD_SUPPORTED:1;
+ uint32_t NON_DESTRUCTIVE_POLLING:1;
+ uint32_t FORCE_CONNECT_SUPPORTED:1;
+ uint32_t FAKED_PATH:1;
+ uint32_t IS_BRANCH_DP_MST_PATH:1;
+ uint32_t IS_ROOT_DP_MST_PATH:1;
+ uint32_t IS_DP_AUDIO_SUPPORTED:1;
+ uint32_t IS_HDMI_AUDIO_SUPPORTED:1;
+ } bits;
+
+ uint32_t raw;
+};
+
+enum display_tri_state {
+ DISPLAY_TRI_STATE_UNKNOWN = 0,
+ DISPLAY_TRI_STATE_TRUE,
+ DISPLAY_TRI_STATE_FALSE
+};
+
+enum {
+ MAX_NUM_OF_LINKS_PER_PATH = 2
+};
+enum {
+ SINK_LINK_INDEX = (uint32_t) (-1)
+};
+enum {
+ ASIC_LINK_INDEX = 0
+};
+
+#endif /* __DAL_DISPLAY_PATH_TYPES_H__ */
diff --git a/drivers/gpu/drm/amd/dal/include/link_service_interface.h b/drivers/gpu/drm/amd/dal/include/link_service_interface.h
new file mode 100644
index 000000000000..2ac93119cc02
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/include/link_service_interface.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_LINK_SERVICE_INTERFACE_H__
+#define __DAL_LINK_SERVICE_INTERFACE_H__
+
+#include "include/link_service_types.h"
+
+/* forward declaration */
+struct link_service;
+struct hw_crtc_timing;
+struct hw_path_mode;
+struct display_path;
+struct hw_path_mode_set;
+struct link_training_preference;
+enum ddc_result;
+
+struct link_service *dal_link_service_create(
+ struct link_service_init_data *init_data);
+
+void dal_link_service_destroy(
+ struct link_service **ls);
+
+enum link_service_type dal_ls_get_link_service_type(
+ struct link_service *link_service);
+
+bool dal_ls_validate_mode_timing(
+ struct link_service *ls,
+ uint32_t display_index,
+ const struct hw_crtc_timing *timing,
+ struct link_validation_flags flags);
+
+bool dal_ls_get_mst_sink_info(
+ struct link_service *ls,
+ uint32_t display_index,
+ struct mst_sink_info *sink_info);
+
+bool dal_ls_get_gtc_sync_status(
+ struct link_service *ls);
+
+bool dal_ls_enable_stream(
+ struct link_service *ls,
+ uint32_t display_index,
+ struct hw_path_mode *path_mode);
+
+bool dal_ls_disable_stream(
+ struct link_service *ls,
+ uint32_t display_index,
+ struct hw_path_mode *poath_mode);
+
+bool dal_ls_optimized_enable_stream(
+ struct link_service *ls,
+ uint32_t display_index,
+ struct display_path *display_path);
+
+void dal_ls_update_stream_features(
+ struct link_service *ls,
+ const struct hw_path_mode *path_mode);
+
+bool dal_ls_blank_stream(
+ struct link_service *ls,
+ uint32_t display_index,
+ struct hw_path_mode *path_mode);
+
+bool dal_ls_unblank_stream(
+ struct link_service *ls,
+ uint32_t display_index,
+ struct hw_path_mode *path_mode);
+
+bool dal_ls_pre_mode_change(
+ struct link_service *ls,
+ uint32_t display_index,
+ struct hw_path_mode *path_mode);
+
+bool dal_ls_post_mode_change(
+ struct link_service *ls,
+ uint32_t display_index,
+ struct hw_path_mode *path_mode);
+
+bool dal_ls_power_on_stream(
+ struct link_service *ls,
+ uint32_t display_index,
+ struct hw_path_mode *path_mode);
+
+bool dal_ls_power_off_stream(
+ struct link_service *ls,
+ uint32_t display_index,
+ struct hw_path_mode *path_mode);
+
+void dal_ls_retrain_link(
+ struct link_service *ls,
+ struct hw_path_mode_set *path_set);
+
+bool dal_ls_get_current_link_setting(
+ struct link_service *ls,
+ struct link_settings *link_settings);
+
+void dal_ls_connect_link(
+ struct link_service *ls,
+ const struct display_path *display_path,
+ bool initial_detection);
+
+void dal_ls_disconnect_link(
+ struct link_service *ls);
+
+bool dal_ls_is_mst_network_present(
+ struct link_service *ls);
+
+void dal_ls_invalidate_down_stream_devices(
+ struct link_service *ls);
+
+bool dal_ls_are_mst_displays_cofunctional(
+ struct link_service *ls,
+ const uint32_t *array_display_index,
+ uint32_t len);
+
+bool dal_ls_is_sink_present_at_display_index(
+ struct link_service *ls,
+ uint32_t display_index);
+
+struct ddc_service *dal_ls_obtain_mst_ddc_service(
+ struct link_service *ls,
+ uint32_t display_index);
+
+void dal_ls_release_mst_ddc_service(
+ struct link_service *ls,
+ struct ddc_service *ddc_service);
+
+void dal_ls_release_hw(
+ struct link_service *ls);
+
+bool dal_ls_associate_link(
+ struct link_service *ls,
+ uint32_t display_index,
+ uint32_t link_index,
+ bool is_internal_link);
+
+bool dal_dpsst_ls_set_overridden_trained_link_settings(
+ struct link_service *ls,
+ const struct link_settings *link_settings);
+
+void dal_dpsst_ls_set_link_training_preference(
+ struct link_service *ls,
+ const struct link_training_preference *ltp);
+
+struct link_training_preference
+ dal_dpsst_ls_get_link_training_preference(
+ struct link_service *ls);
+
+bool dal_ls_should_send_notification(
+ struct link_service *ls);
+
+uint32_t dal_ls_get_notification_display_index(
+ struct link_service *ls);
+
+enum ddc_result dal_dpsst_ls_read_dpcd_data(
+ struct link_service *ls,
+ uint32_t address,
+ uint8_t *data,
+ uint32_t size);
+
+enum ddc_result dal_dpsst_ls_write_dpcd_data(
+ struct link_service *ls,
+ uint32_t address,
+ const uint8_t *data,
+ uint32_t size);
+
+bool dal_ls_is_link_psr_supported(struct link_service *ls);
+
+bool dal_ls_is_stream_drr_supported(struct link_service *ls);
+
+void dal_ls_set_link_psr_capabilities(
+ struct link_service *ls,
+ struct psr_caps *psr_caps);
+
+void dal_ls_get_link_psr_capabilities(
+ struct link_service *ls,
+ struct psr_caps *psr_caps);
+
+#endif /* __DAL_LINK_SERVICE_INTERFACE_H__ */