Laying the groundwork for the AMD DAL display driver.
This patch includes the basic services and defines basic
types required by the display driver, such as:
- ASIC register access
- VBIOS access
- Vector and flat_set data structures
- Display signal types
- ASIC versions and IDs
- HW IDs
- Logging functionality

This patch adds Kconfig options to enable the DAL
display driver.
- DRM_AMD_DAL
- DRM_AMD_DAL_VBIOS_PRESENT
- DRM_AMD_DAL_DCE11_0
- DRM_AMD_DAL_DCE10_0
- DEBUG_KERNEL_DAL

Signed-off-by: Harry Wentland <harry.wentland at amd.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/amd/dal/Kconfig                    |  48 ++
 drivers/gpu/drm/amd/dal/Makefile                   |  21 +
 drivers/gpu/drm/amd/dal/dc/basics/Makefile         |  10 +
 drivers/gpu/drm/amd/dal/dc/basics/conversion.c     | 224 +++++
 drivers/gpu/drm/amd/dal/dc/basics/conversion.h     |  49 ++
 drivers/gpu/drm/amd/dal/dc/basics/grph_object_id.c | 134 +++
 drivers/gpu/drm/amd/dal/dc/basics/logger.c         | 954 +++++++++++++++++++++
 drivers/gpu/drm/amd/dal/dc/basics/logger.h         |  64 ++
 .../gpu/drm/amd/dal/dc/basics/register_logger.c    | 197 +++++
 drivers/gpu/drm/amd/dal/dc/basics/signal_types.c   | 116 +++
 drivers/gpu/drm/amd/dal/dc/basics/vector.c         | 309 +++++++
 11 files changed, 2126 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/dal/Kconfig
 create mode 100644 drivers/gpu/drm/amd/dal/Makefile
 create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/Makefile
 create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/conversion.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/conversion.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/grph_object_id.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/logger.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/logger.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/register_logger.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/signal_types.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/basics/vector.c

diff --git a/drivers/gpu/drm/amd/dal/Kconfig b/drivers/gpu/drm/amd/dal/Kconfig
new file mode 100644
index 000000000000..2289c0b10dae
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/Kconfig
@@ -0,0 +1,48 @@
+menu "Display Engine Configuration"
+       depends on DRM && (DRM_AMDSOC || DRM_AMDGPU)
+
+config DRM_AMD_DAL
+        bool "AMD DAL - Enable new display engine
+        help
+          Choose this option if you want to use the new display engine
+          support for AMD SOC.
+
+          Will be deprecated when the DAL component becomes stable and
+          AMDSOC will fully switch to it.
+
+config DRM_AMD_DAL_VBIOS_PRESENT
+        bool "Video Bios available on board"
+        depends on DRM_AMD_DAL
+        help
+         This option is needed to allow a full range of feature
+        support when working on
+        x86 platforms and there is a VBIOS
+        present in the system
+
+config DRM_AMD_DAL_DCE11_0
+        bool "Carrizo family"
+        depends on DRM_AMD_DAL
+        help
+         Choose this option
+        if you want to have
+        CZ family
+        for display engine
+
+config DRM_AMD_DAL_DCE10_0
+        bool "VI family"
+        depends on DRM_AMD_DAL
+        help
+         Choose this option
+        if you want to have
+        VI family for display
+        engine.
+
+config DEBUG_KERNEL_DAL
+        bool "Enable kgdb break in DAL"
+        depends on DRM_AMD_DAL
+        help
+         Choose this option
+         if you want to hit
+         kdgb_break in assert.
+
+endmenu
diff --git a/drivers/gpu/drm/amd/dal/Makefile b/drivers/gpu/drm/amd/dal/Makefile
new file mode 100644
index 000000000000..25ae4646c4d3
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/Makefile
@@ -0,0 +1,21 @@
+#
+# Makefile for the DAL (Display Abstract Layer), which is a  sub-component
+# of the AMDGPU drm driver.
+# It provides the HW control for display related functionalities.
+
+AMDDALPATH = $(RELATIVE_AMD_DAL_PATH)
+
+subdir-ccflags-y += -Werror
+
+subdir-ccflags-y += -I$(AMDDALPATH)/ -I$(AMDDALPATH)/include
+
+subdir-ccflags-y += -I$(FULL_AMD_DAL_PATH)/dc/inc/
+
+#TODO: remove when Timing Sync feature is complete
+subdir-ccflags-y += -DBUILD_FEATURE_TIMING_SYNC=0
+
+DAL_LIBS = amdgpu_dm dc
+
+AMD_DAL = $(addsuffix /Makefile, $(addprefix 
$(FULL_AMD_DAL_PATH)/,$(DAL_LIBS)))
+
+include $(AMD_DAL)
diff --git a/drivers/gpu/drm/amd/dal/dc/basics/Makefile 
b/drivers/gpu/drm/amd/dal/dc/basics/Makefile
new file mode 100644
index 000000000000..6f382812fae3
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/basics/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the 'utils' sub-component of DAL.
+# It provides the general basic services required by other DAL
+# subcomponents.
+
+BASICS = conversion.o grph_object_id.o logger.o register_logger.o 
signal_types.o vector.o
+
+AMD_DAL_BASICS = $(addprefix $(AMDDALPATH)/dc/basics/,$(BASICS))
+
+AMD_DAL_FILES += $(AMD_DAL_BASICS)
diff --git a/drivers/gpu/drm/amd/dal/dc/basics/conversion.c 
b/drivers/gpu/drm/amd/dal/dc/basics/conversion.c
new file mode 100644
index 000000000000..2f1f3d4ff96b
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/basics/conversion.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 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"
+
+#define DIVIDER 10000
+
+/* S2D13 value in [-3.00...0.9999] */
+#define S2D13_MIN (-3 * DIVIDER)
+#define S2D13_MAX (3 * DIVIDER)
+
+uint16_t fixed_point_to_int_frac(
+       struct fixed31_32 arg,
+       uint8_t integer_bits,
+       uint8_t fractional_bits)
+{
+       int32_t numerator;
+       int32_t divisor = 1 << fractional_bits;
+
+       uint16_t result;
+
+       uint16_t d = (uint16_t)dal_fixed31_32_floor(
+               dal_fixed31_32_abs(
+                       arg));
+
+       if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor))
+               numerator = (uint16_t)dal_fixed31_32_floor(
+                       dal_fixed31_32_mul_int(
+                               arg,
+                               divisor));
+       else {
+               numerator = dal_fixed31_32_floor(
+                       dal_fixed31_32_sub(
+                               dal_fixed31_32_from_int(
+                                       1LL << integer_bits),
+                               dal_fixed31_32_recip(
+                                       dal_fixed31_32_from_int(
+                                               divisor))));
+       }
+
+       if (numerator >= 0)
+               result = (uint16_t)numerator;
+       else
+               result = (uint16_t)(
+               (1 << (integer_bits + fractional_bits + 1)) + numerator);
+
+       if ((result != 0) && dal_fixed31_32_lt(
+               arg, dal_fixed31_32_zero))
+               result |= 1 << (integer_bits + fractional_bits);
+
+       return result;
+}
+/**
+* convert_float_matrix
+* This converts a double into HW register spec defined format S2D13.
+* @param :
+* @return None
+*/
+void convert_float_matrix(
+       uint16_t *matrix,
+       struct fixed31_32 *flt,
+       uint32_t buffer_size)
+{
+       const struct fixed31_32 min_2_13 =
+               dal_fixed31_32_from_fraction(S2D13_MIN, DIVIDER);
+       const struct fixed31_32 max_2_13 =
+               dal_fixed31_32_from_fraction(S2D13_MAX, DIVIDER);
+       uint32_t i;
+
+       for (i = 0; i < buffer_size; ++i) {
+               uint32_t reg_value =
+                               fixed_point_to_int_frac(
+                                       dal_fixed31_32_clamp(
+                                               flt[i],
+                                               min_2_13,
+                                               max_2_13),
+                                               2,
+                                               13);
+
+               matrix[i] = (uint16_t)reg_value;
+       }
+}
+
+static void calculate_adjustments_common(
+       const struct fixed31_32 *ideal_matrix,
+       const struct dc_csc_adjustments *adjustments,
+       struct fixed31_32 *matrix)
+{
+       const struct fixed31_32 sin_hue =
+               dal_fixed31_32_sin(adjustments->hue);
+       const struct fixed31_32 cos_hue =
+               dal_fixed31_32_cos(adjustments->hue);
+
+       const struct fixed31_32 multiplier =
+               dal_fixed31_32_mul(
+                       adjustments->contrast,
+                       adjustments->saturation);
+
+       matrix[0] = dal_fixed31_32_mul(
+               ideal_matrix[0],
+               adjustments->contrast);
+
+       matrix[1] = dal_fixed31_32_mul(
+               ideal_matrix[1],
+               adjustments->contrast);
+
+       matrix[2] = dal_fixed31_32_mul(
+               ideal_matrix[2],
+               adjustments->contrast);
+
+       matrix[4] = dal_fixed31_32_mul(
+               multiplier,
+               dal_fixed31_32_add(
+                       dal_fixed31_32_mul(
+                               ideal_matrix[8],
+                               sin_hue),
+                       dal_fixed31_32_mul(
+                               ideal_matrix[4],
+                               cos_hue)));
+
+       matrix[5] = dal_fixed31_32_mul(
+               multiplier,
+               dal_fixed31_32_add(
+                       dal_fixed31_32_mul(
+                               ideal_matrix[9],
+                               sin_hue),
+                       dal_fixed31_32_mul(
+                               ideal_matrix[5],
+                               cos_hue)));
+
+       matrix[6] = dal_fixed31_32_mul(
+               multiplier,
+               dal_fixed31_32_add(
+                       dal_fixed31_32_mul(
+                               ideal_matrix[10],
+                               sin_hue),
+                       dal_fixed31_32_mul(
+                               ideal_matrix[6],
+                               cos_hue)));
+
+       matrix[7] = ideal_matrix[7];
+
+       matrix[8] = dal_fixed31_32_mul(
+               multiplier,
+               dal_fixed31_32_sub(
+                       dal_fixed31_32_mul(
+                               ideal_matrix[8],
+                               cos_hue),
+                       dal_fixed31_32_mul(
+                               ideal_matrix[4],
+                               sin_hue)));
+
+       matrix[9] = dal_fixed31_32_mul(
+               multiplier,
+               dal_fixed31_32_sub(
+                       dal_fixed31_32_mul(
+                               ideal_matrix[9],
+                               cos_hue),
+                       dal_fixed31_32_mul(
+                               ideal_matrix[5],
+                               sin_hue)));
+
+       matrix[10] = dal_fixed31_32_mul(
+               multiplier,
+               dal_fixed31_32_sub(
+                       dal_fixed31_32_mul(
+                               ideal_matrix[10],
+                               cos_hue),
+                       dal_fixed31_32_mul(
+                               ideal_matrix[6],
+                               sin_hue)));
+
+       matrix[11] = ideal_matrix[11];
+}
+
+void calculate_adjustments(
+       const struct fixed31_32 *ideal_matrix,
+       const struct dc_csc_adjustments *adjustments,
+       struct fixed31_32 *matrix)
+{
+       calculate_adjustments_common(ideal_matrix, adjustments, matrix);
+
+       matrix[3] = dal_fixed31_32_add(
+               ideal_matrix[3],
+               dal_fixed31_32_mul(
+                       adjustments->brightness,
+                       dal_fixed31_32_from_fraction(86, 100)));
+}
+
+void calculate_adjustments_y_only(
+       const struct fixed31_32 *ideal_matrix,
+       const struct dc_csc_adjustments *adjustments,
+       struct fixed31_32 *matrix)
+{
+       calculate_adjustments_common(ideal_matrix, adjustments, matrix);
+
+       matrix[3] = dal_fixed31_32_add(
+               ideal_matrix[3],
+               adjustments->brightness);
+}
+
diff --git a/drivers/gpu/drm/amd/dal/dc/basics/conversion.h 
b/drivers/gpu/drm/amd/dal/dc/basics/conversion.h
new file mode 100644
index 000000000000..24ff47352688
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/basics/conversion.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_CONVERSION_H__
+#define __DAL_CONVERSION_H__
+
+uint16_t fixed_point_to_int_frac(
+       struct fixed31_32 arg,
+       uint8_t integer_bits,
+       uint8_t fractional_bits);
+
+void convert_float_matrix(
+       uint16_t *matrix,
+       struct fixed31_32 *flt,
+       uint32_t buffer_size);
+
+void calculate_adjustments(
+       const struct fixed31_32 *ideal_matrix,
+       const struct dc_csc_adjustments *adjustments,
+       struct fixed31_32 *matrix);
+
+void calculate_adjustments_y_only(
+       const struct fixed31_32 *ideal_matrix,
+       const struct dc_csc_adjustments *adjustments,
+       struct fixed31_32 *matrix);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/dc/basics/grph_object_id.c 
b/drivers/gpu/drm/amd/dal/dc/basics/grph_object_id.c
new file mode 100644
index 000000000000..9c80847d03a9
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/basics/grph_object_id.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+#include "include/grph_object_id.h"
+
+bool dal_graphics_object_id_is_valid(struct graphics_object_id id)
+{
+       bool rc = true;
+
+       switch (id.type) {
+       case OBJECT_TYPE_UNKNOWN:
+               rc = false;
+               break;
+       case OBJECT_TYPE_GPU:
+       case OBJECT_TYPE_ENGINE:
+               /* do NOT check for id.id == 0 */
+               if (id.enum_id == ENUM_ID_UNKNOWN)
+                       rc = false;
+               break;
+       default:
+               if (id.id == 0 || id.enum_id == ENUM_ID_UNKNOWN)
+                       rc = false;
+               break;
+       }
+
+       return rc;
+}
+
+bool dal_graphics_object_id_is_equal(
+       struct graphics_object_id id1,
+       struct graphics_object_id id2)
+{
+       if (false == dal_graphics_object_id_is_valid(id1)) {
+               dm_output_to_console(
+               "%s: Warning: comparing invalid object 'id1'!\n", __func__);
+               return false;
+       }
+
+       if (false == dal_graphics_object_id_is_valid(id2)) {
+               dm_output_to_console(
+               "%s: Warning: comparing invalid object 'id2'!\n", __func__);
+               return false;
+       }
+
+       if (id1.id == id2.id && id1.enum_id == id2.enum_id
+               && id1.type == id2.type)
+               return true;
+
+       return false;
+}
+
+/* Based on internal data members memory layout */
+uint32_t dal_graphics_object_id_to_uint(struct graphics_object_id id)
+{
+       uint32_t object_id = 0;
+
+       object_id = id.id + (id.enum_id << 0x8) + (id.type << 0xc);
+       return object_id;
+}
+
+/*
+ * ******* get specific ID - internal safe cast into specific type *******
+ */
+
+enum controller_id dal_graphics_object_id_get_controller_id(
+       struct graphics_object_id id)
+{
+       if (id.type == OBJECT_TYPE_CONTROLLER)
+               return id.id;
+       return CONTROLLER_ID_UNDEFINED;
+}
+
+enum clock_source_id dal_graphics_object_id_get_clock_source_id(
+       struct graphics_object_id id)
+{
+       if (id.type == OBJECT_TYPE_CLOCK_SOURCE)
+               return id.id;
+       return CLOCK_SOURCE_ID_UNDEFINED;
+}
+
+enum encoder_id dal_graphics_object_id_get_encoder_id(
+       struct graphics_object_id id)
+{
+       if (id.type == OBJECT_TYPE_ENCODER)
+               return id.id;
+       return ENCODER_ID_UNKNOWN;
+}
+
+enum connector_id dal_graphics_object_id_get_connector_id(
+       struct graphics_object_id id)
+{
+       if (id.type == OBJECT_TYPE_CONNECTOR)
+               return id.id;
+       return CONNECTOR_ID_UNKNOWN;
+}
+
+enum audio_id dal_graphics_object_id_get_audio_id(struct graphics_object_id id)
+{
+       if (id.type == OBJECT_TYPE_AUDIO)
+               return id.id;
+       return AUDIO_ID_UNKNOWN;
+}
+
+enum engine_id dal_graphics_object_id_get_engine_id(
+       struct graphics_object_id id)
+{
+       if (id.type == OBJECT_TYPE_ENGINE)
+               return id.id;
+       return ENGINE_ID_UNKNOWN;
+}
+
diff --git a/drivers/gpu/drm/amd/dal/dc/basics/logger.c 
b/drivers/gpu/drm/amd/dal/dc/basics/logger.c
new file mode 100644
index 000000000000..e7938ec9bb7c
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/basics/logger.c
@@ -0,0 +1,954 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+#include <stdarg.h>
+#include "dm_services.h"
+#include "include/dal_types.h"
+#include "include/logger_interface.h"
+#include "logger.h"
+
+/* TODO: for now - empty, use DRM defines from dal services.
+               Need to define appropriate levels of prints, and implement
+               this component
+void dal_log(const char *format, ...)
+{
+}
+*/
+
+/* ----------- Logging Major/Minor names ------------ */
+
+#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
+
+static const struct log_minor_info component_minor_info_tbl[] = {
+       {LOG_MINOR_COMPONENT_LINK_SERVICE, "LS"},
+       {LOG_MINOR_COMPONENT_DAL_INTERFACE, "DalIf"},
+       {LOG_MINOR_COMPONENT_HWSS, "HWSS"},
+       {LOG_MINOR_COMPONENT_ADAPTER_SERVICE, "AS"},
+       {LOG_MINOR_COMPONENT_DISPLAY_SERVICE, "DS"},
+       {LOG_MINOR_COMPONENT_TOPOLOGY_MANAGER, "TM"},
+       {LOG_MINOR_COMPONENT_ENCODER, "Encoder"},
+       {LOG_MINOR_COMPONENT_I2C_AUX, "I2cAux"},
+       {LOG_MINOR_COMPONENT_AUDIO, "Audio"},
+       {LOG_MINOR_COMPONENT_DISPLAY_CAPABILITY_SERVICE, "Dcs"},
+       {LOG_MINOR_COMPONENT_DMCU, "Dmcu"},
+       {LOG_MINOR_COMPONENT_GPU, "GPU"},
+       {LOG_MINOR_COMPONENT_CONTROLLER, "Cntrlr"},
+       {LOG_MINOR_COMPONENT_ISR, "ISR"},
+       {LOG_MINOR_COMPONENT_BIOS, "BIOS"},
+       {LOG_MINOR_COMPONENT_DC, "DC"},
+       {LOG_MINOR_COMPONENT_IRQ_SERVICE, "IRQ SERVICE"},
+
+};
+
+static const struct log_minor_info hw_trace_minor_info_tbl[] = {
+       {LOG_MINOR_HW_TRACE_MST, "Mst" },
+       {LOG_MINOR_HW_TRACE_TRAVIS, "Travis" },
+       {LOG_MINOR_HW_TRACE_HOTPLUG, "Hotplug" },
+       {LOG_MINOR_HW_TRACE_LINK_TRAINING, "LinkTraining" },
+       {LOG_MINOR_HW_TRACE_SET_MODE, "SetMode" },
+       {LOG_MINOR_HW_TRACE_RESUME_S3, "ResumeS3" },
+       {LOG_MINOR_HW_TRACE_RESUME_S4, "ResumeS4" },
+       {LOG_MINOR_HW_TRACE_BOOTUP, "BootUp" },
+       {LOG_MINOR_HW_TRACE_AUDIO, "Audio"},
+       {LOG_MINOR_HW_TRACE_HPD_IRQ, "HpdIrq" },
+       {LOG_MINOR_HW_TRACE_INTERRUPT, "Interrupt" },
+       {LOG_MINOR_HW_TRACE_MPO, "Planes" },
+};
+
+static const struct log_minor_info mst_minor_info_tbl[] = {
+       {LOG_MINOR_MST_IRQ_HPD_RX, "IrqHpdRx"},
+       {LOG_MINOR_MST_IRQ_TIMER, "IrqTimer"},
+       {LOG_MINOR_MST_NATIVE_AUX, "NativeAux"},
+       {LOG_MINOR_MST_SIDEBAND_MSG, "SB"},
+       {LOG_MINOR_MST_MSG_TRANSACTION, "MT"},
+       {LOG_MINOR_MST_SIDEBAND_MSG_PARSED, "SB Parsed"},
+       {LOG_MINOR_MST_MSG_TRANSACTION_PARSED, "MT Parsed"},
+       {LOG_MINOR_MST_AUX_MSG_DPCD_ACCESS, "AuxMsgDpcdAccess"},
+       {LOG_MINOR_MST_PROGRAMMING, "Programming"},
+       {LOG_MINOR_MST_TOPOLOGY_DISCOVERY, "TopologyDiscovery"},
+       {LOG_MINOR_MST_CONVERTER_CAPS, "ConverterCaps"},
+};
+
+static const struct log_minor_info dcs_minor_info_tbl[] = {
+       {LOG_MINOR_DCS_EDID_EMULATOR, "EdidEmul"},
+       {LOG_MINOR_DCS_DONGLE_DETECTION, "DongleDetect"},
+};
+
+static const struct log_minor_info dcp_minor_info_tbl[] = {
+       { LOG_MINOR_DCP_GAMMA_GRPH, "GammaGrph"},
+       { LOG_MINOR_DCP_GAMMA_OVL, "GammaOvl"},
+       { LOG_MINOR_DCP_CSC_GRPH, "CscGrph"},
+       { LOG_MINOR_DCP_CSC_OVL, "CscOvl"},
+       { LOG_MINOR_DCP_SCALER, "Scaler"},
+       { LOG_MINOR_DCP_SCALER_TABLES, "ScalerTables"},
+};
+
+static const struct log_minor_info bios_minor_info_tbl[] = {
+       {LOG_MINOR_BIOS_CMD_TABLE, "CmdTbl"},
+};
+
+static const struct log_minor_info reg_minor_info_tbl[] = {
+       {LOG_MINOR_REGISTER_INDEX, "Index"},
+};
+
+static const struct log_minor_info info_packet_minor_info_tbl[] = {
+       {LOG_MINOR_INFO_PACKETS_HDMI, "Hdmi"},
+};
+
+
+static const struct log_minor_info dsat_minor_info_tbl[] = {
+       {LOG_MINOR_DSAT_LOGGER, "Logger"},
+       {LOG_MINOR_DSAT_EDID_OVERRIDE, "EDID_Override"},
+};
+
+static const struct log_minor_info ec_minor_info_tbl[] = {
+       {LOG_MINOR_EC_PPLIB_NOTIFY, "PPLib_Notify" }, /* PPLib notifies DAL */
+       {LOG_MINOR_EC_PPLIB_QUERY, "PPLib_Query" } /* DAL requested info from
+                                                       PPLib */
+};
+
+static const struct log_minor_info bwm_minor_info_tbl[] = {
+       {LOG_MINOR_BWM_MODE_VALIDATION, "ModeValidation"},
+       {LOG_MINOR_BWM_REQUIRED_BANDWIDTH_CALCS, "Req_Bandw_Calcs"}
+};
+
+static const struct log_minor_info mode_enum_minor_info_tbl[] = {
+       {LOG_MINOR_MODE_ENUM_BEST_VIEW_CANDIDATES, "BestviewCandidates"},
+       {LOG_MINOR_MODE_ENUM_VIEW_SOLUTION, "ViewSolution"},
+       {LOG_MINOR_MODE_ENUM_TS_LIST_BUILD, "TsListBuild"},
+       {LOG_MINOR_MODE_ENUM_TS_LIST, "TsList"},
+       {LOG_MINOR_MODE_ENUM_MASTER_VIEW_LIST, "MasterViewList"},
+       {LOG_MINOR_MODE_ENUM_MASTER_VIEW_LIST_UPDATE, "MasterViewListUpdate"},
+};
+
+static const struct log_minor_info i2caux_minor_info_tbl[] = {
+       {LOG_MINOR_I2C_AUX_LOG, "Log"},
+       {LOG_MINOR_I2C_AUX_AUX_TIMESTAMP, "Timestamp"},
+       {LOG_MINOR_I2C_AUX_CFG, "Config"}
+};
+
+static const struct log_minor_info line_buffer_minor_info_tbl[] = {
+       {LOG_MINOR_LINE_BUFFER_POWERGATING, "PowerGating"}
+};
+
+static const struct log_minor_info hwss_minor_info_tbl[] = {
+       {LOG_MINOR_HWSS_TAPS_VALIDATION, "HWSS Taps"}
+};
+
+static const struct log_minor_info optimization_minor_info_tbl[] = {
+       {LOG_MINOR_OPTMZ_GENERAL, "General Optimizations"},
+       {LOG_MINOR_OPTMZ_DO_NOT_TURN_OFF_VCC_DURING_SET_MODE,
+               "Skip Vcc Off During Set Mode"}
+};
+
+static const struct log_minor_info perf_measure_minor_info_tbl[] = {
+       {LOG_MINOR_PERF_MEASURE_GENERAL, "General Performance Measurement"},
+       {LOG_MINOR_PERF_MEASURE_HEAP_MEMORY, "Heap Memory Management"}
+};
+
+static const struct log_minor_info sync_minor_info_tbl[] = {
+       {LOG_MINOR_SYNC_HW_CLOCK_ADJUST, "Pixel Rate Tune-up"},
+       {LOG_MINOR_SYNC_TIMING, "Timing"}
+};
+
+static const struct log_minor_info backlight_minor_info_tbl[] = {
+       {LOG_MINOR_BACKLIGHT_BRIGHTESS_CAPS, "Caps"},
+       {LOG_MINOR_BACKLIGHT_DMCU_DELTALUT, "DMCU Delta LUT"},
+       {LOG_MINOR_BACKLIGHT_DMCU_BUILD_DELTALUT, "Build DMCU Delta LUT"},
+       {LOG_MINOR_BACKLIGHT_INTERFACE, "Interface"},
+       {LOG_MINOR_BACKLIGHT_LID, "Lid Status"}
+};
+
+
+static const struct log_minor_info override_feature_minor_info_tbl[] = {
+       {LOG_MINOR_FEATURE_OVERRIDE, "overriden feature"},
+};
+
+static const struct log_minor_info detection_minor_info_tbl[] = {
+       {LOG_MINOR_DETECTION_EDID_PARSER, "EDID Parser"},
+       {LOG_MINOR_DETECTION_DP_CAPS, "DP caps"},
+};
+
+static const struct log_minor_info tm_minor_info_tbl[] = {
+       {LOG_MINOR_TM_INFO, "INFO"},
+       {LOG_MINOR_TM_IFACE_TRACE, "IFACE_TRACE"},
+       {LOG_MINOR_TM_RESOURCES, "RESOURCES"},
+       {LOG_MINOR_TM_ENCODER_CTL, "ENCODER_CTL"},
+       {LOG_MINOR_TM_ENG_ASN, "ENG_ASN"},
+       {LOG_MINOR_TM_CONTROLLER_ASN, "CONTROLLER_ASN"},
+       {LOG_MINOR_TM_PWR_GATING, "PWR_GATING"},
+       {LOG_MINOR_TM_BUILD_DSP_PATH, "BUILD_PATH"},
+       {LOG_MINOR_TM_DISPLAY_DETECT, "DISPLAY_DETECT"},
+       {LOG_MINOR_TM_LINK_SRV, "LINK_SRV"},
+       {LOG_MINOR_TM_NOT_IMPLEMENTED, "NOT_IMPL"},
+       {LOG_MINOR_TM_COFUNC_PATH, "COFUNC_PATH"}
+};
+
+static const struct log_minor_info ds_minor_info_tbl[] = {
+       {LOG_MINOR_DS_MODE_SETTING, "Mode_Setting"},
+};
+
+
+struct log_major_mask_info {
+       struct log_major_info major_info;
+       uint32_t default_mask;
+       const struct log_minor_info *minor_tbl;
+       uint32_t tbl_element_cnt;
+};
+
+/* A mask for each Major.
+ * Use a mask or zero. */
+#define LG_ERR_MSK 0xffffffff
+#define LG_WRN_MSK 0xffffffff
+#define LG_TM_MSK (1 << LOG_MINOR_TM_INFO)
+#define LG_FO_MSK (1 << LOG_MINOR_FEATURE_OVERRIDE)
+#define LG_EC_MSK ((1 << LOG_MINOR_EC_PPLIB_NOTIFY) | \
+                       (1 << LOG_MINOR_EC_PPLIB_QUERY))
+#define LG_DSAT_MSK (1 << LOG_MINOR_DSAT_EDID_OVERRIDE)
+#define LG_DT_MSK (1 << LOG_MINOR_DETECTION_EDID_PARSER)
+
+/* IFT - InterFaceTrace */
+#define LG_IFT_MSK (1 << LOG_MINOR_COMPONENT_DC)
+
+
+#define LG_HW_TR_AUD_MSK (1 << LOG_MINOR_HW_TRACE_AUDIO)
+#define LG_HW_TR_INTERRUPT_MSK (1 << LOG_MINOR_HW_TRACE_INTERRUPT) | \
+               (1 << LOG_MINOR_HW_TRACE_HPD_IRQ)
+#define LG_HW_TR_PLANES_MSK (1 << LOG_MINOR_HW_TRACE_MPO)
+#define LG_ALL_MSK 0xffffffff
+#define LG_DCP_MSK ~(1 << LOG_MINOR_DCP_SCALER)
+
+#define LG_SYNC_MSK (1 << LOG_MINOR_SYNC_TIMING)
+
+#define LG_BWM_MSK (1 << LOG_MINOR_BWM_MODE_VALIDATION)
+
+static const struct log_major_mask_info log_major_mask_info_tbl[] = {
+       /* LogMajor                  major name       default     MinorTble     
               tblElementCnt */
+       {{LOG_MAJOR_ERROR,           "Error"       }, LG_ALL_MSK, 
component_minor_info_tbl,    NUM_ELEMENTS(component_minor_info_tbl)},
+       {{LOG_MAJOR_WARNING,         "Warning"     }, LG_ALL_MSK, 
component_minor_info_tbl,    NUM_ELEMENTS(component_minor_info_tbl)},
+       {{LOG_MAJOR_INTERFACE_TRACE, "IfTrace"     }, LG_ALL_MSK, 
component_minor_info_tbl,    NUM_ELEMENTS(component_minor_info_tbl)},
+       {{LOG_MAJOR_HW_TRACE,        "HwTrace"     }, (LG_ALL_MSK &
+                       ~((1 << LOG_MINOR_HW_TRACE_LINK_TRAINING) |
+                       (1 << LOG_MINOR_HW_TRACE_AUDIO))),
+                                                               
hw_trace_minor_info_tbl,     NUM_ELEMENTS(hw_trace_minor_info_tbl)},
+       {{LOG_MAJOR_MST,             "MST"         }, LG_ALL_MSK, 
mst_minor_info_tbl,          NUM_ELEMENTS(mst_minor_info_tbl)},
+       {{LOG_MAJOR_DCS,             "DCS"         }, LG_ALL_MSK, 
dcs_minor_info_tbl,          NUM_ELEMENTS(dcs_minor_info_tbl)},
+       {{LOG_MAJOR_DCP,             "DCP"         }, LG_DCP_MSK, 
dcp_minor_info_tbl,          NUM_ELEMENTS(dcp_minor_info_tbl)},
+       {{LOG_MAJOR_BIOS,            "Bios"        }, LG_ALL_MSK, 
bios_minor_info_tbl,         NUM_ELEMENTS(bios_minor_info_tbl)},
+       {{LOG_MAJOR_REGISTER,        "Register"    }, LG_ALL_MSK, 
reg_minor_info_tbl,          NUM_ELEMENTS(reg_minor_info_tbl)},
+       {{LOG_MAJOR_INFO_PACKETS,    "InfoPacket"  }, LG_ALL_MSK, 
info_packet_minor_info_tbl,  NUM_ELEMENTS(info_packet_minor_info_tbl)},
+       {{LOG_MAJOR_DSAT,            "DSAT"        }, LG_ALL_MSK, 
dsat_minor_info_tbl,         NUM_ELEMENTS(dsat_minor_info_tbl)},
+       {{LOG_MAJOR_EC,              "EC"          }, LG_ALL_MSK, 
ec_minor_info_tbl,           NUM_ELEMENTS(ec_minor_info_tbl)},
+       {{LOG_MAJOR_BWM,             "BWM"         }, LG_BWM_MSK, 
bwm_minor_info_tbl,          NUM_ELEMENTS(bwm_minor_info_tbl)},
+       {{LOG_MAJOR_MODE_ENUM,       "ModeEnum"    }, LG_ALL_MSK, 
mode_enum_minor_info_tbl,    NUM_ELEMENTS(mode_enum_minor_info_tbl)},
+       {{LOG_MAJOR_I2C_AUX,         "I2cAux"      }, LG_ALL_MSK, 
i2caux_minor_info_tbl,       NUM_ELEMENTS(i2caux_minor_info_tbl)},
+       {{LOG_MAJOR_LINE_BUFFER,     "LineBuffer"  }, LG_ALL_MSK, 
line_buffer_minor_info_tbl,  NUM_ELEMENTS(line_buffer_minor_info_tbl)},
+       {{LOG_MAJOR_HWSS,            "HWSS"        }, LG_ALL_MSK, 
hwss_minor_info_tbl,         NUM_ELEMENTS(hwss_minor_info_tbl)},
+       {{LOG_MAJOR_OPTIMIZATION,    "Optimization"}, LG_ALL_MSK, 
optimization_minor_info_tbl, NUM_ELEMENTS(optimization_minor_info_tbl)},
+       {{LOG_MAJOR_PERF_MEASURE,    "PerfMeasure" }, LG_ALL_MSK, 
perf_measure_minor_info_tbl, NUM_ELEMENTS(perf_measure_minor_info_tbl)},
+       {{LOG_MAJOR_SYNC,            "Sync"        }, 
LG_SYNC_MSK,sync_minor_info_tbl,         NUM_ELEMENTS(sync_minor_info_tbl)},
+       {{LOG_MAJOR_BACKLIGHT,       "Backlight"   }, LG_ALL_MSK, 
backlight_minor_info_tbl,    NUM_ELEMENTS(backlight_minor_info_tbl)},
+       {{LOG_MAJOR_INTERRUPTS,      "Interrupts"  }, LG_ALL_MSK, 
component_minor_info_tbl,    NUM_ELEMENTS(component_minor_info_tbl)},
+       {{LOG_MAJOR_TM,              "TM"          }, 0,          
tm_minor_info_tbl,           NUM_ELEMENTS(tm_minor_info_tbl)},
+       {{LOG_MAJOR_DISPLAY_SERVICE, "DS"          }, LG_ALL_MSK, 
ds_minor_info_tbl,           NUM_ELEMENTS(ds_minor_info_tbl)},
+       {{LOG_MAJOR_FEATURE_OVERRIDE, "FeatureOverride" }, LG_ALL_MSK, 
override_feature_minor_info_tbl, NUM_ELEMENTS(override_feature_minor_info_tbl)},
+       {{LOG_MAJOR_DETECTION,       "Detection"   }, LG_ALL_MSK,  
detection_minor_info_tbl,    NUM_ELEMENTS(detection_minor_info_tbl)},
+};
+
+/* ----------- Object init and destruction ----------- */
+static bool construct(struct dc_context *ctx, struct dal_logger *logger)
+{
+       uint32_t i;
+       /* malloc buffer and init offsets */
+
+       logger->log_buffer_size = DAL_LOGGER_BUFFER_MAX_SIZE;
+       logger->log_buffer = (char *)dm_alloc(ctx,
+               logger->log_buffer_size *
+               sizeof(char));
+
+       if (!logger->log_buffer)
+               return false;
+
+       /* todo: Fill buffer with \0 if not done by dal_alloc */
+
+       /* Initialize both offsets to start of buffer (empty) */
+       logger->buffer_read_offset = 0;
+       logger->buffer_write_offset = 0;
+
+       logger->write_wrap_count = 0;
+       logger->read_wrap_count = 0;
+       logger->open_count = 0;
+
+       logger->flags.bits.ENABLE_CONSOLE = 1;
+       logger->flags.bits.ENABLE_BUFFER = 0;
+
+       logger->ctx = ctx;
+
+       /* malloc and init minor mask array */
+       logger->log_enable_mask_minors =
+                       (uint32_t *)dm_alloc(
+                               ctx,
+                               NUM_ELEMENTS(log_major_mask_info_tbl)
+                               * sizeof(uint32_t));
+       if (!logger->log_enable_mask_minors)
+               return false;
+
+
+       /* Set default values for mask */
+       for (i = 0; i < NUM_ELEMENTS(log_major_mask_info_tbl); i++) {
+
+               uint32_t dflt_mask = log_major_mask_info_tbl[i].default_mask;
+
+               logger->log_enable_mask_minors[i] = dflt_mask;
+       }
+
+       return true;
+}
+
+static void destruct(struct dal_logger *logger)
+{
+       if (logger->log_buffer) {
+               dm_free(logger->ctx, logger->log_buffer);
+               logger->log_buffer = NULL;
+       }
+
+       if (logger->log_enable_mask_minors) {
+               dm_free(logger->ctx, logger->log_enable_mask_minors);
+               logger->log_enable_mask_minors = NULL;
+       }
+}
+
+struct dal_logger *dal_logger_create(struct dc_context *ctx)
+{
+       /* malloc struct */
+       struct dal_logger *logger = dm_alloc(ctx, sizeof(struct dal_logger));
+
+       if (!logger)
+               return NULL;
+       if (!construct(ctx, logger)) {
+               dm_free(ctx, logger);
+               return NULL;
+       }
+
+       return logger;
+}
+
+uint32_t dal_logger_destroy(struct dal_logger **logger)
+{
+       if (logger == NULL || *logger == NULL)
+               return 1;
+       destruct(*logger);
+       dm_free((*logger)->ctx, *logger);
+       *logger = NULL;
+
+       return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void lock(struct dal_logger *logger)
+{
+       /* Todo: lock mutex? */
+}
+
+static void unlock(struct dal_logger *logger)
+{
+       /* Todo: unlock mutex */
+}
+
+bool dal_logger_should_log(
+       struct dal_logger *logger,
+       enum log_major major,
+       enum log_minor minor)
+{
+       if (major < LOG_MAJOR_COUNT) {
+
+               uint32_t minor_mask = logger->log_enable_mask_minors[major];
+
+               if ((minor_mask & (1 << minor)) != 0)
+                       return true;
+       }
+
+       return false;
+}
+
+static void log_to_debug_console(struct log_entry *entry)
+{
+       struct dal_logger *logger = entry->logger;
+
+       if (logger->flags.bits.ENABLE_CONSOLE == 0)
+               return;
+
+       if (entry->buf_offset) {
+               switch (entry->major) {
+               case LOG_MAJOR_ERROR:
+                       dm_error("%s", entry->buf);
+                       break;
+               default:
+                       dm_output_to_console("%s", entry->buf);
+                       break;
+               }
+       }
+}
+
+/* Print everything unread existing in log_buffer to debug console*/
+static void flush_to_debug_console(struct dal_logger *logger)
+{
+       int i = logger->buffer_read_offset;
+       char *string_start = &logger->log_buffer[i];
+
+       dm_output_to_console(
+               "---------------- FLUSHING LOG BUFFER ----------------\n");
+       while (i < logger->buffer_write_offset) {
+
+               if (logger->log_buffer[i] == '\0') {
+                       dm_output_to_console("%s", string_start);
+                       string_start = (char *)logger->log_buffer + i + 1;
+               }
+               i++;
+       }
+       dm_output_to_console(
+               "-------------- END FLUSHING LOG BUFFER --------------\n\n");
+}
+
+static void log_to_internal_buffer(struct log_entry *entry)
+{
+
+       uint32_t size = entry->buf_offset;
+       struct dal_logger *logger = entry->logger;
+
+       if (logger->flags.bits.ENABLE_BUFFER == 0)
+               return;
+
+       if (logger->log_buffer == NULL)
+               return;
+
+       if (size > 0 && size < logger->log_buffer_size) {
+
+               int total_free_space = 0;
+               int space_before_wrap = 0;
+
+               if (logger->buffer_write_offset > logger->buffer_read_offset) {
+                       total_free_space = logger->log_buffer_size -
+                                       logger->buffer_write_offset +
+                                       logger->buffer_read_offset;
+                       space_before_wrap = logger->log_buffer_size -
+                                       logger->buffer_write_offset;
+               } else if (logger->buffer_write_offset <
+                               logger->buffer_read_offset) {
+                       total_free_space = logger->log_buffer_size -
+                                       logger->buffer_read_offset +
+                                       logger->buffer_write_offset;
+                       space_before_wrap = total_free_space;
+               } else if (logger->write_wrap_count !=
+                               logger->read_wrap_count) {
+                       /* Buffer is completely full already */
+                       total_free_space = 0;
+                       space_before_wrap = 0;
+               } else {
+                       /* Buffer is empty, start writing at beginning */
+                       total_free_space = logger->log_buffer_size;
+                       space_before_wrap = logger->log_buffer_size;
+                       logger->buffer_write_offset = 0;
+                       logger->buffer_read_offset = 0;
+               }
+
+
+
+
+               if (space_before_wrap > size) {
+                       /* No wrap around, copy 'size' bytes
+                        * from 'entry->buf' to 'log_buffer'
+                        */
+                       dm_memmove(logger->log_buffer +
+                                       logger->buffer_write_offset,
+                                       entry->buf, size);
+                       logger->buffer_write_offset += size;
+
+               } else if (total_free_space > size) {
+                       /* We have enough room without flushing,
+                        * but need to wrap around */
+
+                       int space_after_wrap = total_free_space -
+                                       space_before_wrap;
+
+                       dm_memmove(logger->log_buffer +
+                                       logger->buffer_write_offset,
+                                       entry->buf, space_before_wrap);
+                       dm_memmove(logger->log_buffer, entry->buf +
+                                       space_before_wrap, space_after_wrap);
+
+                       logger->buffer_write_offset = space_after_wrap;
+                       logger->write_wrap_count++;
+
+               } else {
+                       /* Not enough room remaining, we should flush
+                        * existing logs */
+
+                       /* Flush existing unread logs to console */
+                       flush_to_debug_console(logger);
+
+                       /* Start writing to beginning of buffer */
+                       dm_memmove(logger->log_buffer, entry->buf, size);
+                       logger->buffer_write_offset = size;
+                       logger->buffer_read_offset = 0;
+               }
+
+       }
+
+       unlock(logger);
+}
+
+
+static void log_timestamp(struct log_entry *entry)
+{
+       dal_logger_append(entry, "00:00:00 ");
+}
+
+static void log_major_minor(struct log_entry *entry)
+{
+       uint32_t i;
+       enum log_major major = entry->major;
+       enum log_minor minor = entry->minor;
+
+       for (i = 0; i < NUM_ELEMENTS(log_major_mask_info_tbl); i++) {
+
+               const struct log_major_mask_info *maj_mask_info =
+                               &log_major_mask_info_tbl[i];
+
+               if (maj_mask_info->major_info.major == major) {
+
+                       dal_logger_append(entry, "[%s_",
+                                       maj_mask_info->major_info.major_name);
+
+                       if (maj_mask_info->minor_tbl != NULL) {
+                               uint32_t j;
+
+                               for (j = 0; j < maj_mask_info->tbl_element_cnt; 
j++) {
+
+                                       const struct log_minor_info *min_info = 
&maj_mask_info->minor_tbl[j];
+
+                                       if (min_info->minor == minor)
+                                               dal_logger_append(entry, 
"%s]\t", min_info->minor_name);
+                               }
+                       }
+
+                       break;
+               }
+       }
+}
+
+static void log_heading(struct log_entry *entry,
+                       enum log_major major,
+                       enum log_minor minor)
+{
+       log_timestamp(entry);
+       log_major_minor(entry);
+}
+
+
+static void append_entry(
+               struct log_entry *entry,
+               char *buffer,
+               uint32_t buf_size)
+{
+       if (!entry->buf ||
+               entry->buf_offset + buf_size > entry->max_buf_bytes
+       ) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
+       /* Todo: check if off by 1 byte due to \0 anywhere */
+       dm_memmove(entry->buf + entry->buf_offset, buffer, buf_size);
+       entry->buf_offset += buf_size;
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* Warning: Be careful that 'msg' is null terminated and the total size is
+ * less than DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE (256) including '\0'
+ */
+void dal_logger_write(
+       struct dal_logger *logger,
+       enum log_major major,
+       enum log_minor minor,
+       const char *msg,
+       ...)
+{
+
+       if (logger && dal_logger_should_log(logger, major, minor)) {
+
+               uint32_t size;
+               va_list args;
+               char buffer[DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE];
+               struct log_entry entry;
+
+               va_start(args, msg);
+               dal_logger_open(logger, &entry, major, minor);
+
+
+               size = dm_log_to_buffer(
+                       buffer, DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE, msg, args);
+
+               if (size > 0 && size <
+                               DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE - 1) {
+
+                       if (buffer[size] == '\0')
+                               size++; /* Add one for null terminator */
+
+                       /* Concatenate onto end of entry buffer */
+                       append_entry(&entry, buffer, size);
+               } else {
+                       append_entry(&entry,
+                               "LOG_ERROR, line too long or null\n", 35);
+               }
+
+               dal_logger_close(&entry);
+               va_end(args);
+
+       }
+}
+
+
+/* Same as dal_logger_write, except without open() and close(), which must
+ * be done separately.
+ */
+void dal_logger_append(
+       struct log_entry *entry,
+       const char *msg,
+       ...)
+{
+       struct dal_logger *logger;
+
+       if (!entry) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
+       logger = entry->logger;
+
+       if (logger && logger->open_count > 0 &&
+               dal_logger_should_log(logger, entry->major, entry->minor)) {
+
+               uint32_t size;
+               va_list args;
+               char buffer[DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE];
+
+               va_start(args, msg);
+
+               size = dm_log_to_buffer(
+                       buffer, DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE, msg, args);
+
+               if (size < DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE - 1) {
+                       append_entry(entry, buffer, size);
+               } else {
+                       append_entry(entry, "LOG_ERROR, line too long\n", 27);
+               }
+
+               va_end(args);
+       }
+}
+
+
+uint32_t dal_logger_read(
+       struct dal_logger *logger, /* <[in] */
+       uint32_t output_buffer_size, /* <[in] */
+       char *output_buffer, /* >[out] */
+       uint32_t *bytes_read, /* >[out] */
+       bool single_line)
+{
+       uint32_t bytes_remaining = 0;
+       uint32_t bytes_read_count = 0;
+       bool keep_reading = true;
+
+       if (!logger || output_buffer == NULL || output_buffer_size == 0) {
+               BREAK_TO_DEBUGGER();
+               *bytes_read = 0;
+               return 0;
+       }
+
+       lock(logger);
+
+       /* Read until null terminator (if single_line==true,
+        *  max buffer size, or until we've read everything new
+        */
+
+       do {
+               char cur;
+
+               /* Stop when we've read everything */
+               if (logger->buffer_read_offset ==
+                       logger->buffer_write_offset) {
+
+                       break;
+               }
+
+               cur = logger->log_buffer[logger->buffer_read_offset];
+               logger->buffer_read_offset++;
+
+               /* Wrap read pointer if at end */
+               if (logger->buffer_read_offset == logger->log_buffer_size) {
+
+                       logger->buffer_read_offset = 0;
+                       logger->read_wrap_count++;
+               }
+
+               /* Don't send null terminators to buffer */
+               if (cur != '\0') {
+                       output_buffer[bytes_read_count] = cur;
+                       bytes_read_count++;
+               } else if (single_line) {
+                       keep_reading = false;
+               }
+
+       } while (bytes_read_count <= output_buffer_size && keep_reading);
+
+       /* We assume that reading can never be ahead of writing */
+       if (logger->write_wrap_count > logger->read_wrap_count) {
+               bytes_remaining = logger->log_buffer_size -
+                       logger->buffer_read_offset +
+                       logger->buffer_write_offset;
+       } else {
+               bytes_remaining = logger->buffer_write_offset -
+                               logger->buffer_read_offset;
+       }
+
+       /* reset write/read wrap count to 0 if we've read everything */
+       if (bytes_remaining == 0) {
+
+               logger->write_wrap_count = 0;
+               logger->read_wrap_count = 0;
+       }
+
+       *bytes_read = bytes_read_count;
+       unlock(logger);
+
+       return bytes_remaining;
+}
+
+void dal_logger_open(
+               struct dal_logger *logger,
+               struct log_entry *entry, /* out */
+               enum log_major major,
+               enum log_minor minor)
+{
+       if (!entry) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
+       entry->major = LOG_MAJOR_COUNT;
+       entry->minor = 0;
+       entry->logger = logger;
+
+       entry->buf = dm_alloc(
+               logger->ctx,
+               DAL_LOGGER_BUFFER_MAX_SIZE * sizeof(char));
+
+       entry->buf_offset = 0;
+       entry->max_buf_bytes = DAL_LOGGER_BUFFER_MAX_SIZE * sizeof(char);
+
+       logger->open_count++;
+       entry->major = major;
+       entry->minor = minor;
+
+       log_heading(entry, major, minor);
+}
+
+void dal_logger_close(struct log_entry *entry)
+{
+       struct dal_logger *logger = entry->logger;
+
+
+       if (logger && logger->open_count > 0) {
+               logger->open_count--;
+       } else {
+               BREAK_TO_DEBUGGER();
+               goto cleanup;
+       }
+
+       /* --Flush log_entry buffer-- */
+       /* print to kernel console */
+       log_to_debug_console(entry);
+       /* log internally for dsat */
+       log_to_internal_buffer(entry);
+
+       /* TODO: Write end heading */
+
+cleanup:
+       if (entry->buf) {
+               dm_free(entry->logger->ctx, entry->buf);
+               entry->buf = NULL;
+               entry->buf_offset = 0;
+               entry->max_buf_bytes = 0;
+       }
+}
+
+uint32_t dal_logger_get_mask(
+       struct dal_logger *logger,
+       enum log_major lvl_major, enum log_minor lvl_minor)
+{
+       uint32_t log_mask = 0;
+
+       if (logger && lvl_major < LOG_MAJOR_COUNT)
+               log_mask = logger->log_enable_mask_minors[lvl_major];
+
+       log_mask &= 1 << lvl_minor;
+       return log_mask;
+}
+
+uint32_t dal_logger_set_mask(
+       struct dal_logger *logger,
+       enum log_major lvl_major, enum log_minor lvl_minor)
+{
+
+       if (logger && lvl_major < LOG_MAJOR_COUNT) {
+               if (lvl_minor == LOG_MINOR_MASK_ALL) {
+                       logger->log_enable_mask_minors[lvl_major] = 0xFFFFFFFF;
+               } else {
+                       logger->log_enable_mask_minors[lvl_major] |=
+                               (1 << lvl_minor);
+               }
+               return 0;
+       }
+       return 1;
+}
+
+uint32_t dal_logger_get_masks(
+       struct dal_logger *logger,
+       enum log_major lvl_major)
+{
+       uint32_t log_mask = 0;
+
+       if (logger && lvl_major < LOG_MAJOR_COUNT)
+               log_mask = logger->log_enable_mask_minors[lvl_major];
+
+       return log_mask;
+}
+
+void dal_logger_set_masks(
+       struct dal_logger *logger,
+       enum log_major lvl_major, uint32_t log_mask)
+{
+       if (logger && lvl_major < LOG_MAJOR_COUNT)
+               logger->log_enable_mask_minors[lvl_major] = log_mask;
+}
+
+uint32_t dal_logger_unset_mask(
+       struct dal_logger *logger,
+       enum log_major lvl_major, enum log_minor lvl_minor)
+{
+
+       if (lvl_major < LOG_MAJOR_COUNT) {
+               if (lvl_minor == LOG_MINOR_MASK_ALL) {
+                       logger->log_enable_mask_minors[lvl_major] = 0;
+               } else {
+                       logger->log_enable_mask_minors[lvl_major] &=
+                               ~(1 << lvl_minor);
+               }
+               return 0;
+       }
+       return 1;
+}
+
+uint32_t dal_logger_get_flags(
+               struct dal_logger *logger)
+{
+
+       return logger->flags.value;
+}
+
+void dal_logger_set_flags(
+               struct dal_logger *logger,
+               union logger_flags flags)
+{
+
+       logger->flags = flags;
+}
+
+
+uint32_t dal_logger_get_buffer_size(struct dal_logger *logger)
+{
+       return DAL_LOGGER_BUFFER_MAX_SIZE;
+}
+
+uint32_t dal_logger_set_buffer_size(
+               struct dal_logger *logger,
+               uint32_t new_size)
+{
+       /* ToDo: implement dynamic size */
+
+       /* return new size */
+       return DAL_LOGGER_BUFFER_MAX_SIZE;
+}
+
+
+const struct log_major_info *dal_logger_enum_log_major_info(
+               struct dal_logger *logger,
+               unsigned int enum_index)
+{
+       const struct log_major_info *major_info;
+
+       if (enum_index >= NUM_ELEMENTS(log_major_mask_info_tbl))
+               return NULL;
+
+       major_info = &log_major_mask_info_tbl[enum_index].major_info;
+       return major_info;
+}
+
+const struct log_minor_info *dal_logger_enum_log_minor_info(
+               struct dal_logger *logger,
+               enum log_major major,
+               unsigned int enum_index)
+{
+       const struct log_minor_info *minor_info = NULL;
+       uint32_t i;
+
+       for (i = 0; i < NUM_ELEMENTS(log_major_mask_info_tbl); i++) {
+
+               const struct log_major_mask_info *maj_mask_info =
+                               &log_major_mask_info_tbl[i];
+
+               if (maj_mask_info->major_info.major == major) {
+
+                       if (maj_mask_info->minor_tbl != NULL) {
+                               uint32_t j;
+
+                               for (j = 0; j < maj_mask_info->tbl_element_cnt; 
j++) {
+
+                                       minor_info = 
&maj_mask_info->minor_tbl[j];
+
+                                       if (minor_info->minor == enum_index)
+                                               return minor_info;
+                               }
+                       }
+
+                       break;
+               }
+       }
+       return NULL;
+
+}
+
diff --git a/drivers/gpu/drm/amd/dal/dc/basics/logger.h 
b/drivers/gpu/drm/amd/dal/dc/basics/logger.h
new file mode 100644
index 000000000000..fba5ec3264b6
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/basics/logger.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_LOGGER_H__
+#define __DAL_LOGGER_H__
+
+/* Structure for keeping track of offsets, buffer, etc */
+
+#define DAL_LOGGER_BUFFER_MAX_SIZE 2048
+#define DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE 256
+
+
+#include "include/logger_types.h"
+
+struct dal_logger {
+
+       /* How far into the circular buffer has been read by dsat
+        * Read offset should never cross write offset. Write \0's to
+        * read data just to be sure?
+        */
+       uint32_t buffer_read_offset;
+
+       /* How far into the circular buffer we have written
+        * Write offset should never cross read offset
+        */
+       uint32_t buffer_write_offset;
+
+       uint32_t write_wrap_count;
+       uint32_t read_wrap_count;
+
+       uint32_t open_count;
+
+       char *log_buffer;       /* Pointer to malloc'ed buffer */
+       uint32_t log_buffer_size; /* Size of circular buffer */
+
+       uint32_t *log_enable_mask_minors; /*array of masks for major elements*/
+
+       union logger_flags flags;
+       struct dc_context *ctx;
+};
+
+#endif /* __DAL_LOGGER_H__ */
diff --git a/drivers/gpu/drm/amd/dal/dc/basics/register_logger.c 
b/drivers/gpu/drm/amd/dal/dc/basics/register_logger.c
new file mode 100644
index 000000000000..6d32b1bdf35c
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/basics/register_logger.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+#include "include/dal_types.h"
+#include "include/logger_interface.h"
+#include "logger.h"
+
+/******************************************************************************
+ * Register Logger.
+ * A facility to create register R/W logs.
+ * Currently used for DAL Test.
+ *****************************************************************************/
+
+/******************************************************************************
+ * Private structures
+ *****************************************************************************/
+struct dal_reg_dump_stack_location {
+       const char *current_caller_func;
+       long current_pid;
+       long current_tgid;
+       uint32_t rw_count;/* register access counter for current function. */
+};
+
+/* This the maximum number of nested calls to the 'reg_dump' facility. */
+#define DAL_REG_DUMP_STACK_MAX_SIZE 32
+
+struct dal_reg_dump_stack {
+       int32_t stack_pointer;
+       struct dal_reg_dump_stack_location
+               stack_locations[DAL_REG_DUMP_STACK_MAX_SIZE];
+       uint32_t total_rw_count; /* Total count for *all* functions. */
+};
+
+static struct dal_reg_dump_stack reg_dump_stack = {0};
+
+/******************************************************************************
+ * Private functions
+ *****************************************************************************/
+
+/* Check if current process is the one which requested register dump.
+ * The reason for the check:
+ * mmCRTC_STATUS_FRAME_COUNT is accessed by 
dal_controller_get_vblank_counter().
+ * Which runs all the time when at least one display is connected.
+ * (Triggered by drm_mode_page_flip_ioctl()). */
+static bool is_reg_dump_process(void)
+{
+       uint32_t i;
+
+       /* walk the list of our processes */
+       for (i = 0; i < reg_dump_stack.stack_pointer; i++) {
+               struct dal_reg_dump_stack_location *stack_location
+                                       = &reg_dump_stack.stack_locations[i];
+
+               if (stack_location->current_pid == dm_get_pid()
+                       && stack_location->current_tgid == dm_get_tgid())
+                       return true;
+       }
+
+       return false;
+}
+
+static bool dal_reg_dump_stack_is_empty(void)
+{
+       if (reg_dump_stack.stack_pointer <= 0)
+               return true;
+       else
+               return false;
+}
+
+static struct dal_reg_dump_stack_location *dal_reg_dump_stack_push(void)
+{
+       struct dal_reg_dump_stack_location *current_location = NULL;
+
+       if (reg_dump_stack.stack_pointer >= DAL_REG_DUMP_STACK_MAX_SIZE) {
+               /* stack is full */
+               dm_output_to_console("[REG_DUMP]: %s: stack is full!\n",
+                               __func__);
+       } else {
+               current_location =
+               &reg_dump_stack.stack_locations[reg_dump_stack.stack_pointer];
+               ++reg_dump_stack.stack_pointer;
+       }
+
+       return current_location;
+}
+
+static struct dal_reg_dump_stack_location *dal_reg_dump_stack_pop(void)
+{
+       struct dal_reg_dump_stack_location *current_location = NULL;
+
+       if (dal_reg_dump_stack_is_empty()) {
+               /* stack is empty */
+               dm_output_to_console("[REG_DUMP]: %s: stack is empty!\n",
+                               __func__);
+       } else {
+               --reg_dump_stack.stack_pointer;
+               current_location =
+               &reg_dump_stack.stack_locations[reg_dump_stack.stack_pointer];
+       }
+
+       return current_location;
+}
+
+/******************************************************************************
+ * Public functions
+ *****************************************************************************/
+
+void dal_reg_logger_push(const char *caller_func)
+{
+       struct dal_reg_dump_stack_location *free_stack_location;
+
+       free_stack_location = dal_reg_dump_stack_push();
+
+       if (NULL == free_stack_location)
+               return;
+
+       dm_memset(free_stack_location, 0, sizeof(*free_stack_location));
+
+       free_stack_location->current_caller_func = caller_func;
+       free_stack_location->current_pid = dm_get_pid();
+       free_stack_location->current_tgid = dm_get_tgid();
+
+       dm_output_to_console("[REG_DUMP]:%s - start (pid:%ld, tgid:%ld)\n",
+               caller_func,
+               free_stack_location->current_pid,
+               free_stack_location->current_tgid);
+}
+
+void dal_reg_logger_pop(void)
+{
+       struct dal_reg_dump_stack_location *top_stack_location;
+
+       top_stack_location = dal_reg_dump_stack_pop();
+
+       if (NULL == top_stack_location) {
+               dm_output_to_console("[REG_DUMP]:%s - Stack is Empty!\n",
+                               __func__);
+               return;
+       }
+
+       dm_output_to_console(
+       "[REG_DUMP]:%s - end."\
+       " Reg R/W Count: Total=%d Function=%d. (pid:%ld, tgid:%ld)\n",
+                       top_stack_location->current_caller_func,
+                       reg_dump_stack.total_rw_count,
+                       top_stack_location->rw_count,
+                       dm_get_pid(),
+                       dm_get_tgid());
+
+       dm_memset(top_stack_location, 0, sizeof(*top_stack_location));
+}
+
+void dal_reg_logger_rw_count_increment(void)
+{
+       ++reg_dump_stack.total_rw_count;
+
+       ++reg_dump_stack.stack_locations
+               [reg_dump_stack.stack_pointer - 1].rw_count;
+}
+
+bool dal_reg_logger_should_dump_register(void)
+{
+       if (true == dal_reg_dump_stack_is_empty())
+               return false;
+
+       if (false == is_reg_dump_process())
+               return false;
+
+       return true;
+}
+
+/******************************************************************************
+ * End of File.
+ *****************************************************************************/
diff --git a/drivers/gpu/drm/amd/dal/dc/basics/signal_types.c 
b/drivers/gpu/drm/amd/dal/dc/basics/signal_types.c
new file mode 100644
index 000000000000..44447e07803a
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/basics/signal_types.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+#include "include/signal_types.h"
+
+bool dc_is_hdmi_signal(enum signal_type signal)
+{
+       return (signal == SIGNAL_TYPE_HDMI_TYPE_A);
+}
+
+bool dc_is_dp_sst_signal(enum signal_type signal)
+{
+       return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
+               signal == SIGNAL_TYPE_EDP);
+}
+
+bool dc_is_dp_signal(enum signal_type signal)
+{
+       return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
+               signal == SIGNAL_TYPE_EDP ||
+               signal == SIGNAL_TYPE_DISPLAY_PORT_MST);
+}
+
+bool dc_is_dp_external_signal(enum signal_type signal)
+{
+       return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
+               signal == SIGNAL_TYPE_DISPLAY_PORT_MST);
+}
+
+bool dc_is_analog_signal(enum signal_type signal)
+{
+       switch (signal) {
+       case SIGNAL_TYPE_RGB:
+               return true;
+       break;
+       default:
+               return false;
+       }
+}
+
+bool dc_is_embedded_signal(enum signal_type signal)
+{
+       return (signal == SIGNAL_TYPE_EDP || signal == SIGNAL_TYPE_LVDS);
+}
+
+bool dc_is_dvi_signal(enum signal_type signal)
+{
+       switch (signal) {
+       case SIGNAL_TYPE_DVI_SINGLE_LINK:
+       case SIGNAL_TYPE_DVI_DUAL_LINK:
+               return true;
+       break;
+       default:
+               return false;
+       }
+}
+
+bool dc_is_dvi_single_link_signal(enum signal_type signal)
+{
+       return (signal == SIGNAL_TYPE_DVI_SINGLE_LINK);
+}
+
+bool dc_is_dual_link_signal(enum signal_type signal)
+{
+       return (signal == SIGNAL_TYPE_DVI_DUAL_LINK);
+}
+
+bool dc_is_audio_capable_signal(enum signal_type signal)
+{
+       return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
+               signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
+               dc_is_hdmi_signal(signal) ||
+               signal == SIGNAL_TYPE_WIRELESS);
+}
+
+/*
+ * @brief
+ * Returns whether the signal is compatible
+ * with other digital encoder signal types.
+ * This is true for DVI, LVDS, and HDMI signal types.
+ */
+bool dc_is_digital_encoder_compatible_signal(enum signal_type signal)
+{
+       switch (signal) {
+       case SIGNAL_TYPE_DVI_SINGLE_LINK:
+       case SIGNAL_TYPE_DVI_DUAL_LINK:
+       case SIGNAL_TYPE_HDMI_TYPE_A:
+       case SIGNAL_TYPE_LVDS:
+               return true;
+       default:
+               return false;
+       }
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/basics/vector.c 
b/drivers/gpu/drm/amd/dal/dc/basics/vector.c
new file mode 100644
index 000000000000..32ca6b13a3bd
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/basics/vector.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+#include "include/vector.h"
+
+bool dal_vector_construct(
+       struct vector *vector,
+       struct dc_context *ctx,
+       uint32_t capacity,
+       uint32_t struct_size)
+{
+       vector->container = NULL;
+
+       if (!struct_size || !capacity) {
+               /* Container must be non-zero size*/
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       vector->container = dm_alloc(ctx, struct_size * capacity);
+       if (vector->container == NULL)
+               return false;
+       vector->capacity = capacity;
+       vector->struct_size = struct_size;
+       vector->count = 0;
+       vector->ctx = ctx;
+       return true;
+}
+
+bool dal_vector_presized_costruct(
+       struct vector *vector,
+       struct dc_context *ctx,
+       uint32_t count,
+       void *initial_value,
+       uint32_t struct_size)
+{
+       uint32_t i;
+
+       vector->container = NULL;
+
+       if (!struct_size || !count) {
+               /* Container must be non-zero size*/
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       vector->container = dm_alloc(ctx, struct_size * count);
+
+       if (vector->container == NULL)
+               return false;
+
+       /* If caller didn't supply initial value then the default
+        * of all zeros is expected, which is exactly what dal_alloc()
+        * initialises the memory to. */
+       if (NULL != initial_value) {
+               for (i = 0; i < count; ++i)
+                       dm_memmove(
+                               vector->container + i * struct_size,
+                               initial_value,
+                               struct_size);
+       }
+
+       vector->capacity = count;
+       vector->struct_size = struct_size;
+       vector->count = count;
+       return true;
+}
+
+struct vector *dal_vector_presized_create(
+       struct dc_context *ctx,
+       uint32_t size,
+       void *initial_value,
+       uint32_t struct_size)
+{
+       struct vector *vector = dm_alloc(ctx, sizeof(struct vector));
+
+       if (vector == NULL)
+               return NULL;
+
+       if (dal_vector_presized_costruct(
+               vector, ctx, size, initial_value, struct_size))
+               return vector;
+
+       BREAK_TO_DEBUGGER();
+       dm_free(ctx, vector);
+       return NULL;
+}
+
+struct vector *dal_vector_create(
+       struct dc_context *ctx,
+       uint32_t capacity,
+       uint32_t struct_size)
+{
+       struct vector *vector = dm_alloc(ctx, sizeof(struct vector));
+
+       if (vector == NULL)
+               return NULL;
+
+       if (dal_vector_construct(vector, ctx, capacity, struct_size))
+               return vector;
+
+
+       BREAK_TO_DEBUGGER();
+       dm_free(ctx, vector);
+       return NULL;
+}
+
+void dal_vector_destruct(
+       struct vector *vector)
+{
+       if (vector->container != NULL)
+               dm_free(vector->ctx, vector->container);
+       vector->count = 0;
+       vector->capacity = 0;
+}
+
+void dal_vector_destroy(
+       struct vector **vector)
+{
+       if (vector == NULL || *vector == NULL)
+               return;
+       dal_vector_destruct(*vector);
+       dm_free((*vector)->ctx, *vector);
+       *vector = NULL;
+}
+
+uint32_t dal_vector_get_count(
+       const struct vector *vector)
+{
+       return vector->count;
+}
+
+void *dal_vector_at_index(
+       const struct vector *vector,
+       uint32_t index)
+{
+       if (vector->container == NULL || index >= vector->count)
+               return NULL;
+       return vector->container + (index * vector->struct_size);
+}
+
+bool dal_vector_remove_at_index(
+       struct vector *vector,
+       uint32_t index)
+{
+       if (index >= vector->count)
+               return false;
+
+       if (index != vector->count - 1)
+               dm_memmove(
+                       vector->container + (index * vector->struct_size),
+                       vector->container + ((index + 1) * vector->struct_size),
+                       (vector->count - index - 1) * vector->struct_size);
+       vector->count -= 1;
+
+       return true;
+}
+
+void dal_vector_set_at_index(
+       const struct vector *vector,
+       const void *what,
+       uint32_t index)
+{
+       void *where = dal_vector_at_index(vector, index);
+
+       if (!where) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+       dm_memmove(
+               where,
+               what,
+               vector->struct_size);
+}
+
+static inline uint32_t calc_increased_capacity(
+       uint32_t old_capacity)
+{
+       return old_capacity * 2;
+}
+
+bool dal_vector_insert_at(
+       struct vector *vector,
+       const void *what,
+       uint32_t position)
+{
+       uint8_t *insert_address;
+
+       if (vector->count == vector->capacity) {
+               if (!dal_vector_reserve(
+                       vector,
+                       calc_increased_capacity(vector->capacity)))
+                       return false;
+       }
+
+       insert_address = vector->container + (vector->struct_size * position);
+
+       if (vector->count && position < vector->count)
+               dm_memmove(
+                       insert_address + vector->struct_size,
+                       insert_address,
+                       vector->struct_size * (vector->count - position));
+
+       dm_memmove(
+               insert_address,
+               what,
+               vector->struct_size);
+
+       vector->count++;
+
+       return true;
+}
+
+bool dal_vector_append(
+       struct vector *vector,
+       const void *item)
+{
+       return dal_vector_insert_at(vector, item, vector->count);
+}
+
+struct vector *dal_vector_clone(
+       const struct vector *vector)
+{
+       struct vector *vec_cloned;
+       uint32_t count;
+
+       /* create new vector */
+       count = dal_vector_get_count(vector);
+
+       if (count == 0)
+               /* when count is 0 we still want to create clone of the vector
+                */
+               vec_cloned = dal_vector_create(
+                       vector->ctx,
+                       vector->capacity,
+                       vector->struct_size);
+       else
+               /* Call "presized create" version, independently of how the
+                * original vector was created.
+                * The owner of original vector must know how to treat the new
+                * vector - as "presized" or as "regular".
+                * But from vector point of view it doesn't matter. */
+               vec_cloned = dal_vector_presized_create(vector->ctx, count,
+                       NULL,/* no initial value */
+                       vector->struct_size);
+
+       if (NULL == vec_cloned) {
+               BREAK_TO_DEBUGGER();
+               return NULL;
+       }
+
+       /* copy vector's data */
+       dm_memmove(vec_cloned->container, vector->container,
+                       vec_cloned->struct_size * vec_cloned->capacity);
+
+       return vec_cloned;
+}
+
+uint32_t dal_vector_capacity(const struct vector *vector)
+{
+       return vector->capacity;
+}
+
+bool dal_vector_reserve(struct vector *vector, uint32_t capacity)
+{
+       void *new_container;
+
+       if (capacity <= vector->capacity)
+               return true;
+
+       new_container = dm_realloc(vector->ctx, vector->container,
+               capacity * vector->struct_size);
+
+       if (new_container) {
+               vector->container = new_container;
+               vector->capacity = capacity;
+               return true;
+       }
+
+       return false;
+}
+
+void dal_vector_clear(struct vector *vector)
+{
+       vector->count = 0;
+}
-- 
2.1.4

Reply via email to