Manages all DCE GPIO pins. The pins are represented as generic IO
handles as well as handles dedicated for certain functions, such as
DDC, HPD, and DVO.

Signed-off-by: Harry Wentland <harry.wentland at amd.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/amd/dal/dc/gpio/Makefile           |  32 +
 .../gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.c | 882 +++++++++++++++++++++
 .../gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.h |  46 ++
 .../drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.c |  81 ++
 .../drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.h |  32 +
 .../gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.c | 366 +++++++++
 .../gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.h |  47 ++
 .../amd/dal/dc/gpio/dce110/hw_translate_dce110.c   | 400 ++++++++++
 .../amd/dal/dc/gpio/dce110/hw_translate_dce110.h   |  34 +
 drivers/gpu/drm/amd/dal/dc/gpio/ddc.c              | 290 +++++++
 drivers/gpu/drm/amd/dal/dc/gpio/ddc.h              |  45 ++
 .../drm/amd/dal/dc/gpio/diagnostics/hw_ddc_diag.c  |  97 +++
 .../drm/amd/dal/dc/gpio/diagnostics/hw_ddc_diag.h  |  34 +
 .../amd/dal/dc/gpio/diagnostics/hw_factory_diag.c  |  65 ++
 .../amd/dal/dc/gpio/diagnostics/hw_factory_diag.h  |  32 +
 .../drm/amd/dal/dc/gpio/diagnostics/hw_hpd_diag.c  | 101 +++
 .../drm/amd/dal/dc/gpio/diagnostics/hw_hpd_diag.h  |  35 +
 .../dal/dc/gpio/diagnostics/hw_translate_diag.c    |  41 +
 .../dal/dc/gpio/diagnostics/hw_translate_diag.h    |  34 +
 drivers/gpu/drm/amd/dal/dc/gpio/gpio.h             |  48 ++
 drivers/gpu/drm/amd/dal/dc/gpio/gpio_base.c        | 279 +++++++
 drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.c     | 386 +++++++++
 drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.h     |  57 ++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c           | 104 +++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.h           |  60 ++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c       |  93 +++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.h       |  71 ++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.c          | 407 ++++++++++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.h          | 129 +++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.c      |  92 +++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.h      |  47 ++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.c      |  85 ++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.h      |  79 ++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.c           |  87 ++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.h           |  45 ++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c     |  77 ++
 drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.h     |  50 ++
 drivers/gpu/drm/amd/dal/dc/gpio/irq.c              | 180 +++++
 drivers/gpu/drm/amd/dal/dc/gpio/irq.h              |  42 +
 39 files changed, 5112 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/Makefile
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/ddc.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/ddc.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_ddc_diag.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_ddc_diag.h
 create mode 100644 
drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_factory_diag.c
 create mode 100644 
drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_factory_diag.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_hpd_diag.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_hpd_diag.h
 create mode 100644 
drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_translate_diag.c
 create mode 100644 
drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_translate_diag.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/gpio.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/gpio_base.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.h
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/irq.c
 create mode 100644 drivers/gpu/drm/amd/dal/dc/gpio/irq.h

diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/Makefile 
b/drivers/gpu/drm/amd/dal/dc/gpio/Makefile
new file mode 100644
index 000000000000..2507bb564946
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/Makefile
@@ -0,0 +1,32 @@
+#
+# Makefile for the 'gpio' sub-component of DAL.
+# It provides the control and status of HW GPIO pins.
+
+GPIO = ddc.o gpio_base.o gpio_service.o hw_ddc.o hw_factory.o \
+       hw_gpio.o hw_gpio_pad.o hw_gpio_pin.o hw_hpd.o hw_translate.o irq.o
+
+AMD_DAL_GPIO = $(addprefix $(AMDDALPATH)/dc/gpio/,$(GPIO))
+
+AMD_DAL_FILES += $(AMD_DAL_GPIO)
+
+
+###############################################################################
+# DCE 11x
+###############################################################################
+ifdef CONFIG_DRM_AMD_DAL_DCE11_0
+GPIO_DCE110 = hw_translate_dce110.o hw_factory_dce110.o hw_hpd_dce110.o \
+       hw_ddc_dce110.o
+
+AMD_DAL_GPIO_DCE110 = $(addprefix $(AMDDALPATH)/dc/gpio/dce110/,$(GPIO_DCE110))
+
+AMD_DAL_FILES += $(AMD_DAL_GPIO_DCE110)
+endif
+
+###############################################################################
+# Diagnostics on FPGA
+###############################################################################
+GPIO_DIAG_FPGA = hw_translate_diag.o hw_factory_diag.o hw_hpd_diag.o 
hw_ddc_diag.o
+
+AMD_DAL_GPIO_DIAG_FPGA = $(addprefix 
$(AMDDALPATH)/dc/gpio/diagnostics/,$(GPIO_DIAG_FPGA))
+
+AMD_DAL_FILES += $(AMD_DAL_GPIO_DIAG_FPGA)
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.c
new file mode 100644
index 000000000000..8ff899c5ad12
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.c
@@ -0,0 +1,882 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+#include "include/gpio_types.h"
+#include "../hw_gpio_pin.h"
+#include "../hw_gpio.h"
+#include "../hw_ddc.h"
+
+/*
+ * Header of this unit
+ */
+#include "hw_ddc_dce110.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+#include "dce/dce_11_0_d.h"
+#include "dce/dce_11_0_sh_mask.h"
+
+#define ADDR_DDC_SETUP pin->addr.dc_i2c_ddc_setup
+/*
+ * This unit
+ */
+static void destruct(
+       struct hw_ddc_dce110 *pin)
+{
+       dal_hw_ddc_destruct(&pin->base);
+}
+
+static void destroy(
+       struct hw_gpio_pin **ptr)
+{
+       struct hw_ddc_dce110 *pin = DDC_DCE110_FROM_BASE(*ptr);
+
+       destruct(pin);
+
+       dm_free((*ptr)->ctx, pin);
+
+       *ptr = NULL;
+}
+
+struct hw_ddc_dce110_init {
+       struct hw_gpio_pin_reg hw_gpio_data_reg;
+       struct hw_ddc_mask hw_ddc_mask;
+       struct hw_ddc_dce110_addr hw_ddc_dce110_addr;
+};
+
+static const struct hw_ddc_dce110_init
+       hw_ddc_dce110_init_data[GPIO_DDC_LINE_COUNT] = {
+       /* GPIO_DDC_LINE_DDC1 */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDC1_MASK,
+                               DC_GPIO_DDC1_MASK__DC_GPIO_DDC1DATA_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC1_A,
+                               DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC1_EN,
+                               DC_GPIO_DDC1_EN__DC_GPIO_DDC1DATA_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC1_Y,
+                               DC_GPIO_DDC1_Y__DC_GPIO_DDC1DATA_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDC1_MASK__DC_GPIO_DDC1DATA_MASK_MASK,
+                       DC_GPIO_DDC1_MASK__DC_GPIO_DDC1DATA_PD_EN_MASK,
+                       DC_GPIO_DDC1_MASK__DC_GPIO_DDC1DATA_RECV_MASK,
+                       DC_GPIO_DDC1_MASK__AUX_PAD1_MODE_MASK,
+                       DC_GPIO_DDC1_MASK__AUX1_POL_MASK,
+                       DC_GPIO_DDC1_MASK__DC_GPIO_DDC1CLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDC1_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_DDC2 */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDC2_MASK,
+                               DC_GPIO_DDC2_MASK__DC_GPIO_DDC2DATA_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC2_A,
+                               DC_GPIO_DDC2_A__DC_GPIO_DDC2DATA_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC2_EN,
+                               DC_GPIO_DDC2_EN__DC_GPIO_DDC2DATA_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC2_Y,
+                               DC_GPIO_DDC2_Y__DC_GPIO_DDC2DATA_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDC2_MASK__DC_GPIO_DDC2DATA_MASK_MASK,
+                       DC_GPIO_DDC2_MASK__DC_GPIO_DDC2DATA_PD_EN_MASK,
+                       DC_GPIO_DDC2_MASK__DC_GPIO_DDC2DATA_RECV_MASK,
+                       DC_GPIO_DDC2_MASK__AUX_PAD2_MODE_MASK,
+                       DC_GPIO_DDC2_MASK__AUX2_POL_MASK,
+                       DC_GPIO_DDC2_MASK__DC_GPIO_DDC2CLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDC2_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_DDC3 */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDC3_MASK,
+                               DC_GPIO_DDC3_MASK__DC_GPIO_DDC3DATA_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC3_A,
+                               DC_GPIO_DDC3_A__DC_GPIO_DDC3DATA_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC3_EN,
+                               DC_GPIO_DDC3_EN__DC_GPIO_DDC3DATA_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC3_Y,
+                               DC_GPIO_DDC3_Y__DC_GPIO_DDC3DATA_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDC3_MASK__DC_GPIO_DDC3DATA_MASK_MASK,
+                       DC_GPIO_DDC3_MASK__DC_GPIO_DDC3DATA_PD_EN_MASK,
+                       DC_GPIO_DDC3_MASK__DC_GPIO_DDC3DATA_RECV_MASK,
+                       DC_GPIO_DDC3_MASK__AUX_PAD3_MODE_MASK,
+                       DC_GPIO_DDC3_MASK__AUX3_POL_MASK,
+                       DC_GPIO_DDC3_MASK__DC_GPIO_DDC3CLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDC3_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_DDC4 */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDC4_MASK,
+                               DC_GPIO_DDC4_MASK__DC_GPIO_DDC4DATA_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC4_A,
+                               DC_GPIO_DDC4_A__DC_GPIO_DDC4DATA_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC4_EN,
+                               DC_GPIO_DDC4_EN__DC_GPIO_DDC4DATA_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC4_Y,
+                               DC_GPIO_DDC4_Y__DC_GPIO_DDC4DATA_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDC4_MASK__DC_GPIO_DDC4DATA_MASK_MASK,
+                       DC_GPIO_DDC4_MASK__DC_GPIO_DDC4DATA_PD_EN_MASK,
+                       DC_GPIO_DDC4_MASK__DC_GPIO_DDC4DATA_RECV_MASK,
+                       DC_GPIO_DDC4_MASK__AUX_PAD4_MODE_MASK,
+                       DC_GPIO_DDC4_MASK__AUX4_POL_MASK,
+                       DC_GPIO_DDC4_MASK__DC_GPIO_DDC4CLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDC4_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_DDC5 */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDC5_MASK,
+                               DC_GPIO_DDC5_MASK__DC_GPIO_DDC5DATA_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC5_A,
+                               DC_GPIO_DDC5_A__DC_GPIO_DDC5DATA_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC5_EN,
+                               DC_GPIO_DDC5_EN__DC_GPIO_DDC5DATA_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC5_Y,
+                               DC_GPIO_DDC5_Y__DC_GPIO_DDC5DATA_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDC5_MASK__DC_GPIO_DDC5DATA_MASK_MASK,
+                       DC_GPIO_DDC5_MASK__DC_GPIO_DDC5DATA_PD_EN_MASK,
+                       DC_GPIO_DDC5_MASK__DC_GPIO_DDC5DATA_RECV_MASK,
+                       DC_GPIO_DDC5_MASK__AUX_PAD5_MODE_MASK,
+                       DC_GPIO_DDC5_MASK__AUX5_POL_MASK,
+                       DC_GPIO_DDC5_MASK__DC_GPIO_DDC5CLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDC5_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_DDC6 */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDC6_MASK,
+                               DC_GPIO_DDC6_MASK__DC_GPIO_DDC6DATA_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC6_A,
+                               DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC6_EN,
+                               DC_GPIO_DDC6_EN__DC_GPIO_DDC6DATA_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC6_Y,
+                               DC_GPIO_DDC6_Y__DC_GPIO_DDC6DATA_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDC6_MASK__DC_GPIO_DDC6DATA_MASK_MASK,
+                       DC_GPIO_DDC6_MASK__DC_GPIO_DDC6DATA_PD_EN_MASK,
+                       DC_GPIO_DDC6_MASK__DC_GPIO_DDC6DATA_RECV_MASK,
+                       DC_GPIO_DDC6_MASK__AUX_PAD6_MODE_MASK,
+                       DC_GPIO_DDC6_MASK__AUX6_POL_MASK,
+                       DC_GPIO_DDC6_MASK__DC_GPIO_DDC6CLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDC6_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_DDC_VGA */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDCVGA_MASK,
+                       DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGADATA_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDCVGA_A,
+                               DC_GPIO_DDCVGA_A__DC_GPIO_DDCVGADATA_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDCVGA_EN,
+                               DC_GPIO_DDCVGA_EN__DC_GPIO_DDCVGADATA_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDCVGA_Y,
+                               DC_GPIO_DDCVGA_Y__DC_GPIO_DDCVGADATA_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGADATA_MASK_MASK,
+                       DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGADATA_PD_EN_MASK,
+                       DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGADATA_RECV_MASK,
+                       DC_GPIO_DDCVGA_MASK__AUX_PADVGA_MODE_MASK,
+                       DC_GPIO_DDCVGA_MASK__AUXVGA_POL_MASK,
+                       DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGACLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDCVGA_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_I2CPAD */
+       {
+               {
+                       {
+                               mmDC_GPIO_I2CPAD_MASK,
+                               DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_I2CPAD_A,
+                               DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_I2CPAD_EN,
+                               DC_GPIO_I2CPAD_EN__DC_GPIO_SDA_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_I2CPAD_Y,
+                               DC_GPIO_I2CPAD_Y__DC_GPIO_SDA_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_MASK_MASK,
+                       DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_PD_DIS_MASK,
+                       DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_RECV_MASK,
+                       0,
+                       0,
+                       0
+               },
+               {
+                       0
+               }
+       }
+};
+
+static const struct hw_ddc_dce110_init
+       hw_ddc_dce110_init_clock[GPIO_DDC_LINE_COUNT] = {
+       /* GPIO_DDC_LINE_DDC1 */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDC1_MASK,
+                               DC_GPIO_DDC1_MASK__DC_GPIO_DDC1CLK_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC1_A,
+                               DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC1_EN,
+                               DC_GPIO_DDC1_EN__DC_GPIO_DDC1CLK_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC1_Y,
+                               DC_GPIO_DDC1_Y__DC_GPIO_DDC1CLK_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDC1_MASK__DC_GPIO_DDC1CLK_MASK_MASK,
+                       DC_GPIO_DDC1_MASK__DC_GPIO_DDC1CLK_PD_EN_MASK,
+                       DC_GPIO_DDC1_MASK__DC_GPIO_DDC1CLK_RECV_MASK,
+                       DC_GPIO_DDC1_MASK__AUX_PAD1_MODE_MASK,
+                       DC_GPIO_DDC1_MASK__AUX1_POL_MASK,
+                       DC_GPIO_DDC1_MASK__DC_GPIO_DDC1CLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDC1_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_DDC2 */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDC2_MASK,
+                               DC_GPIO_DDC2_MASK__DC_GPIO_DDC2CLK_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC2_A,
+                               DC_GPIO_DDC2_A__DC_GPIO_DDC2CLK_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC2_EN,
+                               DC_GPIO_DDC2_EN__DC_GPIO_DDC2CLK_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC2_Y,
+                               DC_GPIO_DDC2_Y__DC_GPIO_DDC2CLK_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDC2_MASK__DC_GPIO_DDC2CLK_MASK_MASK,
+                       DC_GPIO_DDC2_MASK__DC_GPIO_DDC2CLK_PD_EN_MASK,
+                       DC_GPIO_DDC2_MASK__DC_GPIO_DDC2CLK_RECV_MASK,
+                       DC_GPIO_DDC2_MASK__AUX_PAD2_MODE_MASK,
+                       DC_GPIO_DDC2_MASK__AUX2_POL_MASK,
+                       DC_GPIO_DDC2_MASK__DC_GPIO_DDC2CLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDC2_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_DDC3 */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDC3_MASK,
+                               DC_GPIO_DDC3_MASK__DC_GPIO_DDC3CLK_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC3_A,
+                               DC_GPIO_DDC3_A__DC_GPIO_DDC3CLK_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC3_EN,
+                               DC_GPIO_DDC3_EN__DC_GPIO_DDC3CLK_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC3_Y,
+                               DC_GPIO_DDC3_Y__DC_GPIO_DDC3CLK_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDC3_MASK__DC_GPIO_DDC3CLK_MASK_MASK,
+                       DC_GPIO_DDC3_MASK__DC_GPIO_DDC3CLK_PD_EN_MASK,
+                       DC_GPIO_DDC3_MASK__DC_GPIO_DDC3CLK_RECV_MASK,
+                       DC_GPIO_DDC3_MASK__AUX_PAD3_MODE_MASK,
+                       DC_GPIO_DDC3_MASK__AUX3_POL_MASK,
+                       DC_GPIO_DDC3_MASK__DC_GPIO_DDC3CLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDC3_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_DDC4 */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDC4_MASK,
+                               DC_GPIO_DDC4_MASK__DC_GPIO_DDC4CLK_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC4_A,
+                               DC_GPIO_DDC4_A__DC_GPIO_DDC4CLK_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC4_EN,
+                               DC_GPIO_DDC4_EN__DC_GPIO_DDC4CLK_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC4_Y,
+                               DC_GPIO_DDC4_Y__DC_GPIO_DDC4CLK_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDC4_MASK__DC_GPIO_DDC4CLK_MASK_MASK,
+                       DC_GPIO_DDC4_MASK__DC_GPIO_DDC4CLK_PD_EN_MASK,
+                       DC_GPIO_DDC4_MASK__DC_GPIO_DDC4CLK_RECV_MASK,
+                       DC_GPIO_DDC4_MASK__AUX_PAD4_MODE_MASK,
+                       DC_GPIO_DDC4_MASK__AUX4_POL_MASK,
+                       DC_GPIO_DDC4_MASK__DC_GPIO_DDC4CLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDC4_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_DDC5 */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDC5_MASK,
+                               DC_GPIO_DDC5_MASK__DC_GPIO_DDC5CLK_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC5_A,
+                               DC_GPIO_DDC5_A__DC_GPIO_DDC5CLK_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC5_EN,
+                               DC_GPIO_DDC5_EN__DC_GPIO_DDC5CLK_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC5_Y,
+                               DC_GPIO_DDC5_Y__DC_GPIO_DDC5CLK_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDC5_MASK__DC_GPIO_DDC5CLK_MASK_MASK,
+                       DC_GPIO_DDC5_MASK__DC_GPIO_DDC5CLK_PD_EN_MASK,
+                       DC_GPIO_DDC5_MASK__DC_GPIO_DDC5CLK_RECV_MASK,
+                       DC_GPIO_DDC5_MASK__AUX_PAD5_MODE_MASK,
+                       DC_GPIO_DDC5_MASK__AUX5_POL_MASK,
+                       DC_GPIO_DDC5_MASK__DC_GPIO_DDC5CLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDC5_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_DDC6 */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDC6_MASK,
+                               DC_GPIO_DDC6_MASK__DC_GPIO_DDC6CLK_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC6_A,
+                               DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC6_EN,
+                               DC_GPIO_DDC6_EN__DC_GPIO_DDC6CLK_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDC6_Y,
+                               DC_GPIO_DDC6_Y__DC_GPIO_DDC6CLK_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDC6_MASK__DC_GPIO_DDC6CLK_MASK_MASK,
+                       DC_GPIO_DDC6_MASK__DC_GPIO_DDC6CLK_PD_EN_MASK,
+                       DC_GPIO_DDC6_MASK__DC_GPIO_DDC6CLK_RECV_MASK,
+                       DC_GPIO_DDC6_MASK__AUX_PAD6_MODE_MASK,
+                       DC_GPIO_DDC6_MASK__AUX6_POL_MASK,
+                       DC_GPIO_DDC6_MASK__DC_GPIO_DDC6CLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDC6_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_DDC_VGA */
+       {
+               {
+                       {
+                               mmDC_GPIO_DDCVGA_MASK,
+                               DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGACLK_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDCVGA_A,
+                               DC_GPIO_DDCVGA_A__DC_GPIO_DDCVGACLK_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDCVGA_EN,
+                               DC_GPIO_DDCVGA_EN__DC_GPIO_DDCVGACLK_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_DDCVGA_Y,
+                               DC_GPIO_DDCVGA_Y__DC_GPIO_DDCVGACLK_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGACLK_MASK_MASK,
+                       DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGADATA_PD_EN_MASK,
+                       DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGACLK_RECV_MASK,
+                       DC_GPIO_DDCVGA_MASK__AUX_PADVGA_MODE_MASK,
+                       DC_GPIO_DDCVGA_MASK__AUXVGA_POL_MASK,
+                       DC_GPIO_DDCVGA_MASK__DC_GPIO_DDCVGACLK_STR_MASK
+               },
+               {
+                       mmDC_I2C_DDCVGA_SETUP
+               }
+       },
+       /* GPIO_DDC_LINE_I2CPAD */
+       {
+               {
+                       {
+                               mmDC_GPIO_I2CPAD_MASK,
+                               DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_I2CPAD_A,
+                               DC_GPIO_I2CPAD_A__DC_GPIO_SCL_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_I2CPAD_EN,
+                               DC_GPIO_I2CPAD_EN__DC_GPIO_SCL_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_I2CPAD_Y,
+                               DC_GPIO_I2CPAD_Y__DC_GPIO_SCL_Y_MASK
+                       }
+               },
+               {
+                       DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_MASK_MASK,
+                       DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_PD_DIS_MASK,
+                       DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_RECV_MASK,
+                       0,
+                       0,
+                       0
+               },
+               {
+                       0
+               }
+       }
+};
+
+static void setup_i2c_polling(
+       struct dc_context *ctx,
+       const uint32_t addr,
+       bool enable_detect,
+       bool detect_mode)
+{
+       uint32_t value;
+
+       value = dm_read_reg(ctx, addr);
+
+       set_reg_field_value(
+               value,
+               enable_detect,
+               DC_I2C_DDC1_SETUP,
+               DC_I2C_DDC1_ENABLE);
+
+       set_reg_field_value(
+               value,
+               enable_detect,
+               DC_I2C_DDC1_SETUP,
+               DC_I2C_DDC1_EDID_DETECT_ENABLE);
+
+       if (enable_detect)
+               set_reg_field_value(
+                       value,
+                       detect_mode,
+                       DC_I2C_DDC1_SETUP,
+                       DC_I2C_DDC1_EDID_DETECT_MODE);
+
+       dm_write_reg(ctx, addr, value);
+}
+
+static enum gpio_result set_config(
+       struct hw_gpio_pin *ptr,
+       const struct gpio_config_data *config_data)
+{
+       struct hw_ddc_dce110 *pin = DDC_DCE110_FROM_BASE(ptr);
+       struct hw_gpio *hw_gpio = NULL;
+       uint32_t addr;
+       uint32_t regval;
+       uint32_t ddc_data_pd_en = 0;
+       uint32_t ddc_clk_pd_en = 0;
+       uint32_t aux_pad_mode = 0;
+
+       hw_gpio = &pin->base.base;
+
+       if (hw_gpio == NULL) {
+               ASSERT_CRITICAL(false);
+               return GPIO_RESULT_NULL_HANDLE;
+       }
+
+       /* switch dual mode GPIO to I2C/AUX mode */
+
+       addr = hw_gpio->pin_reg.DC_GPIO_DATA_MASK.addr;
+
+       regval = dm_read_reg(ptr->ctx, addr);
+
+       ddc_data_pd_en = get_reg_field_value(
+                       regval,
+                       DC_GPIO_DDC1_MASK,
+                       DC_GPIO_DDC1DATA_PD_EN);
+
+       ddc_clk_pd_en = get_reg_field_value(
+                       regval,
+                       DC_GPIO_DDC1_MASK,
+                       DC_GPIO_DDC1CLK_PD_EN);
+
+       aux_pad_mode = get_reg_field_value(
+                       regval,
+                       DC_GPIO_DDC1_MASK,
+                       AUX_PAD1_MODE);
+
+       switch (config_data->config.ddc.type) {
+       case GPIO_DDC_CONFIG_TYPE_MODE_I2C:
+               /* On plug-in, there is a transient level on the pad
+                * which must be discharged through the internal pull-down.
+                * Enable internal pull-down, 2.5msec discharge time
+                * is required for detection of AUX mode */
+               if (hw_gpio->base.en != GPIO_DDC_LINE_VIP_PAD) {
+                       if (!ddc_data_pd_en || !ddc_clk_pd_en) {
+                               set_reg_field_value(
+                                       regval,
+                                       1,
+                                       DC_GPIO_DDC1_MASK,
+                                       DC_GPIO_DDC1DATA_PD_EN);
+
+                               set_reg_field_value(
+                                       regval,
+                                       1,
+                                       DC_GPIO_DDC1_MASK,
+                                       DC_GPIO_DDC1CLK_PD_EN);
+
+                               dm_write_reg(ptr->ctx, addr, regval);
+
+                               if (config_data->type ==
+                                       GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
+                                       /* should not affect normal I2C R/W */
+                                       /* [anaumov] in DAL2, there was
+                                        * 
dc_service_delay_in_microseconds(2500); */
+                                       dm_sleep_in_milliseconds(ptr->ctx, 3);
+                       }
+               } else {
+                       uint32_t reg2 = regval;
+                       uint32_t sda_pd_dis = 0;
+                       uint32_t scl_pd_dis = 0;
+
+                       sda_pd_dis = get_reg_field_value(
+                                       reg2,
+                                       DC_GPIO_I2CPAD_MASK,
+                                       DC_GPIO_SDA_PD_DIS);
+
+                       scl_pd_dis = get_reg_field_value(
+                                       reg2,
+                                       DC_GPIO_I2CPAD_MASK,
+                                       DC_GPIO_SCL_PD_DIS);
+
+                       if (sda_pd_dis) {
+                               sda_pd_dis = 0;
+
+                               dm_write_reg(ptr->ctx, addr, reg2);
+
+                               if (config_data->type ==
+                                       GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
+                                       /* should not affect normal I2C R/W */
+                                       /* [anaumov] in DAL2, there was
+                                        * 
dc_service_delay_in_microseconds(2500); */
+                                       dm_sleep_in_milliseconds(ptr->ctx, 3);
+                       }
+
+                       if (!scl_pd_dis) {
+                               scl_pd_dis = 1;
+
+                               dm_write_reg(ptr->ctx, addr, reg2);
+
+                               if (config_data->type ==
+                                       GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
+                                       /* should not affect normal I2C R/W */
+                                       /* [anaumov] in DAL2, there was
+                                        * 
dc_service_delay_in_microseconds(2500); */
+                                       dm_sleep_in_milliseconds(ptr->ctx, 3);
+                       }
+               }
+
+               if (aux_pad_mode) {
+                       /* let pins to get de-asserted
+                        * before setting pad to I2C mode */
+                       if (config_data->config.ddc.data_en_bit_present ||
+                               config_data->config.ddc.clock_en_bit_present)
+                               /* [anaumov] in DAL2, there was
+                                * dc_service_delay_in_microseconds(2000); */
+                               dm_sleep_in_milliseconds(ptr->ctx, 2);
+
+                       /* set the I2C pad mode */
+                       /* read the register again,
+                        * some bits may have been changed */
+                       regval = dm_read_reg(ptr->ctx, addr);
+
+                       set_reg_field_value(
+                               regval,
+                               0,
+                               DC_GPIO_DDC1_MASK,
+                               AUX_PAD1_MODE);
+
+                       dm_write_reg(ptr->ctx, addr, regval);
+               }
+
+               return GPIO_RESULT_OK;
+       case GPIO_DDC_CONFIG_TYPE_MODE_AUX:
+               /* set the AUX pad mode */
+               if (!aux_pad_mode) {
+                       set_reg_field_value(
+                               regval,
+                               1,
+                               DC_GPIO_DDC1_MASK,
+                               AUX_PAD1_MODE);
+
+                       dm_write_reg(ptr->ctx, addr, regval);
+               }
+
+               return GPIO_RESULT_OK;
+       case GPIO_DDC_CONFIG_TYPE_POLL_FOR_CONNECT:
+               if ((hw_gpio->base.en >= GPIO_DDC_LINE_DDC1) &&
+                       (hw_gpio->base.en <= GPIO_DDC_LINE_DDC_VGA)) {
+                       setup_i2c_polling(
+                               ptr->ctx, ADDR_DDC_SETUP, 1, 0);
+                       return GPIO_RESULT_OK;
+               }
+       break;
+       case GPIO_DDC_CONFIG_TYPE_POLL_FOR_DISCONNECT:
+               if ((hw_gpio->base.en >= GPIO_DDC_LINE_DDC1) &&
+                       (hw_gpio->base.en <= GPIO_DDC_LINE_DDC_VGA)) {
+                       setup_i2c_polling(
+                               ptr->ctx, ADDR_DDC_SETUP, 1, 1);
+                       return GPIO_RESULT_OK;
+               }
+       break;
+       case GPIO_DDC_CONFIG_TYPE_DISABLE_POLLING:
+               if ((hw_gpio->base.en >= GPIO_DDC_LINE_DDC1) &&
+                       (hw_gpio->base.en <= GPIO_DDC_LINE_DDC_VGA)) {
+                       setup_i2c_polling(
+                               ptr->ctx, ADDR_DDC_SETUP, 0, 0);
+                       return GPIO_RESULT_OK;
+               }
+       break;
+       }
+
+       BREAK_TO_DEBUGGER();
+
+       return GPIO_RESULT_NON_SPECIFIC_ERROR;
+}
+
+static const struct hw_gpio_pin_funcs funcs = {
+       .destroy = destroy,
+       .open = dal_hw_ddc_open,
+       .get_value = dal_hw_gpio_get_value,
+       .set_value = dal_hw_gpio_set_value,
+       .set_config = set_config,
+       .change_mode = dal_hw_gpio_change_mode,
+       .close = dal_hw_gpio_close,
+};
+
+
+static bool construct(
+       struct hw_ddc_dce110 *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx)
+{
+       const struct hw_ddc_dce110_init *init;
+
+       if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       if (!dal_hw_ddc_construct(&pin->base, id, en, ctx)) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       pin->base.base.base.funcs = &funcs;
+
+       switch (id) {
+       case GPIO_ID_DDC_DATA:
+               init = hw_ddc_dce110_init_data + en;
+
+               pin->base.base.pin_reg = init->hw_gpio_data_reg;
+               pin->base.mask = init->hw_ddc_mask;
+               pin->addr = init->hw_ddc_dce110_addr;
+
+               return true;
+       case GPIO_ID_DDC_CLOCK:
+               init = hw_ddc_dce110_init_clock + en;
+
+               pin->base.base.pin_reg = init->hw_gpio_data_reg;
+               pin->base.mask = init->hw_ddc_mask;
+               pin->addr = init->hw_ddc_dce110_addr;
+
+               return true;
+       default:
+               ASSERT_CRITICAL(false);
+       }
+
+       return false;
+}
+
+struct hw_gpio_pin *dal_hw_ddc_dce110_create(
+       struct dc_context *ctx,
+       enum gpio_id id,
+       uint32_t en)
+{
+       struct hw_ddc_dce110 *pin = dm_alloc(ctx, sizeof(struct hw_ddc_dce110));
+
+       if (!pin) {
+               ASSERT_CRITICAL(false);
+               return NULL;
+       }
+
+       if (construct(pin, id, en, ctx))
+               return &pin->base.base.base;
+
+       ASSERT_CRITICAL(false);
+
+       dm_free(ctx, pin);
+
+       return NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.h
new file mode 100644
index 000000000000..683036984f6f
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_ddc_dce110.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_DDC_DCE110_H__
+#define __DAL_HW_DDC_DCE110_H__
+
+struct hw_ddc_dce110_addr {
+       uint32_t dc_i2c_ddc_setup;
+};
+
+struct hw_ddc_dce110 {
+       struct hw_ddc base;
+       struct hw_ddc_dce110_addr addr;
+};
+
+#define DDC_DCE110_FROM_BASE(ddc_base) \
+       container_of((HW_DDC_FROM_BASE(ddc_base)), struct hw_ddc_dce110, base)
+
+struct hw_gpio_pin *dal_hw_ddc_dce110_create(
+       struct dc_context *ctx,
+       enum gpio_id id,
+       uint32_t en);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.c
new file mode 100644
index 000000000000..bdeb60173d0e
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2013-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+
+#include "dm_services.h"
+#include "include/gpio_types.h"
+#include "../hw_factory.h"
+
+/*
+ * Header of this unit
+ */
+
+#include "../hw_gpio_pin.h"
+#include "../hw_gpio.h"
+#include "../hw_ddc.h"
+#include "../hw_hpd.h"
+
+#include "hw_factory_dce110.h"
+
+#include "hw_hpd_dce110.h"
+#include "hw_ddc_dce110.h"
+
+/* fucntion table */
+static const struct hw_factory_funcs funcs = {
+       .create_ddc_data = dal_hw_ddc_dce110_create,
+       .create_ddc_clock = dal_hw_ddc_dce110_create,
+       .create_generic = NULL,
+       .create_hpd = dal_hw_hpd_dce110_create,
+       .create_gpio_pad = NULL,
+       .create_sync = NULL,
+       .create_gsl = NULL,
+};
+
+/*
+ * dal_hw_factory_dce110_init
+ *
+ * @brief
+ * Initialize HW factory function pointers and pin info
+ *
+ * @param
+ * struct hw_factory *factory - [out] struct of function pointers
+ */
+void dal_hw_factory_dce110_init(struct hw_factory *factory)
+{
+       /*TODO check ASIC CAPs*/
+       factory->number_of_pins[GPIO_ID_DDC_DATA] = 8;
+       factory->number_of_pins[GPIO_ID_DDC_CLOCK] = 8;
+       factory->number_of_pins[GPIO_ID_GENERIC] = 7;
+       factory->number_of_pins[GPIO_ID_HPD] = 6;
+       factory->number_of_pins[GPIO_ID_GPIO_PAD] = 31;
+       factory->number_of_pins[GPIO_ID_VIP_PAD] = 0;
+       factory->number_of_pins[GPIO_ID_SYNC] = 2;
+       factory->number_of_pins[GPIO_ID_GSL] = 4;
+
+       factory->funcs = &funcs;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.h
new file mode 100644
index 000000000000..ecf06ed0d587
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_factory_dce110.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2013-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_FACTORY_DCE110_H__
+#define __DAL_HW_FACTORY_DCE110_H__
+
+/* Initialize HW factory function pointers and pin info */
+void dal_hw_factory_dce110_init(struct hw_factory *factory);
+
+#endif /* __DAL_HW_FACTORY_DCE110_H__ */
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.c
new file mode 100644
index 000000000000..a90115cdd55d
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+#include "include/gpio_types.h"
+#include "../hw_gpio_pin.h"
+#include "../hw_gpio.h"
+#include "../hw_hpd.h"
+
+/*
+ * Header of this unit
+ */
+#include "hw_hpd_dce110.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+#include "dce/dce_11_0_d.h"
+#include "dce/dce_11_0_sh_mask.h"
+
+/*
+ * This unit
+ */
+
+static void destruct(
+       struct hw_hpd_dce110 *pin)
+{
+       dal_hw_hpd_destruct(&pin->base);
+}
+
+static void destroy(
+       struct hw_gpio_pin **ptr)
+{
+       struct hw_hpd_dce110 *pin = HPD_DCE110_FROM_BASE(*ptr);
+
+       destruct(pin);
+
+       dm_free((*ptr)->ctx, pin);
+
+       *ptr = NULL;
+}
+
+struct hw_gpio_generic_dce110_init {
+       struct hw_gpio_pin_reg hw_gpio_data_reg;
+       struct hw_hpd_dce110_addr addr;
+};
+
+static const struct hw_gpio_generic_dce110_init
+       hw_gpio_generic_dce110_init[GPIO_HPD_COUNT] = {
+       /* GPIO_HPD_1 */
+       {
+               {
+                       {
+                               mmDC_GPIO_HPD_MASK,
+                               DC_GPIO_HPD_MASK__DC_GPIO_HPD1_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_A,
+                               DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_EN,
+                               DC_GPIO_HPD_EN__DC_GPIO_HPD1_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_Y,
+                               DC_GPIO_HPD_Y__DC_GPIO_HPD1_Y_MASK
+                       }
+               },
+               {
+                       mmHPD0_DC_HPD_INT_STATUS,
+                       mmHPD0_DC_HPD_TOGGLE_FILT_CNTL
+               }
+       },
+       /* GPIO_HPD_2 */
+       {
+               {
+                       {
+                               mmDC_GPIO_HPD_MASK,
+                               DC_GPIO_HPD_MASK__DC_GPIO_HPD2_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_A,
+                               DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_EN,
+                               DC_GPIO_HPD_EN__DC_GPIO_HPD2_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_Y,
+                               DC_GPIO_HPD_Y__DC_GPIO_HPD2_Y_MASK
+                       }
+               },
+               {
+                       mmHPD1_DC_HPD_INT_STATUS,
+                       mmHPD1_DC_HPD_TOGGLE_FILT_CNTL
+               }
+       },
+       /* GPIO_HPD_3 */
+       {
+               {
+                       {
+                               mmDC_GPIO_HPD_MASK,
+                               DC_GPIO_HPD_MASK__DC_GPIO_HPD3_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_A,
+                               DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_EN,
+                               DC_GPIO_HPD_EN__DC_GPIO_HPD3_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_Y,
+                               DC_GPIO_HPD_Y__DC_GPIO_HPD3_Y_MASK
+                       }
+               },
+               {
+                       mmHPD2_DC_HPD_INT_STATUS,
+                       mmHPD2_DC_HPD_TOGGLE_FILT_CNTL
+               }
+       },
+       /* GPIO_HPD_4 */
+       {
+               {
+                       {
+                               mmDC_GPIO_HPD_MASK,
+                               DC_GPIO_HPD_MASK__DC_GPIO_HPD4_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_A,
+                               DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_EN,
+                               DC_GPIO_HPD_EN__DC_GPIO_HPD4_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_Y,
+                               DC_GPIO_HPD_Y__DC_GPIO_HPD4_Y_MASK
+                       }
+               },
+               {
+                       mmHPD3_DC_HPD_INT_STATUS,
+                       mmHPD3_DC_HPD_TOGGLE_FILT_CNTL
+               }
+       },
+       /* GPIO_HPD_5 */
+       {
+               {
+                       {
+                               mmDC_GPIO_HPD_MASK,
+                               DC_GPIO_HPD_MASK__DC_GPIO_HPD5_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_A,
+                               DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_EN,
+                               DC_GPIO_HPD_EN__DC_GPIO_HPD5_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_Y,
+                               DC_GPIO_HPD_Y__DC_GPIO_HPD5_Y_MASK
+                       }
+               },
+               {
+                       mmHPD4_DC_HPD_INT_STATUS,
+                       mmHPD4_DC_HPD_TOGGLE_FILT_CNTL
+               }
+       },
+       /* GPIO_HPD_6 */
+       {
+               {
+                       {
+                               mmDC_GPIO_HPD_MASK,
+                               DC_GPIO_HPD_MASK__DC_GPIO_HPD6_MASK_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_A,
+                               DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_EN,
+                               DC_GPIO_HPD_EN__DC_GPIO_HPD6_EN_MASK
+                       },
+                       {
+                               mmDC_GPIO_HPD_Y,
+                               DC_GPIO_HPD_Y__DC_GPIO_HPD6_Y_MASK
+                       }
+               },
+               {
+                       mmHPD5_DC_HPD_INT_STATUS,
+                       mmHPD5_DC_HPD_TOGGLE_FILT_CNTL
+               }
+       }
+};
+
+static enum gpio_result get_value(
+       const struct hw_gpio_pin *ptr,
+       uint32_t *value)
+{
+       struct hw_hpd_dce110 *pin = HPD_DCE110_FROM_BASE(ptr);
+
+       /* in Interrupt mode we ask for SENSE bit */
+
+       if (ptr->mode == GPIO_MODE_INTERRUPT) {
+               uint32_t regval;
+               uint32_t hpd_delayed = 0;
+               uint32_t hpd_sense = 0;
+
+               regval = dm_read_reg(
+                               ptr->ctx,
+                               pin->addr.DC_HPD_INT_STATUS);
+
+               hpd_delayed = get_reg_field_value(
+                               regval,
+                               DC_HPD_INT_STATUS,
+                               DC_HPD_SENSE_DELAYED);
+
+               hpd_sense = get_reg_field_value(
+                               regval,
+                               DC_HPD_INT_STATUS,
+                               DC_HPD_SENSE);
+
+               *value = hpd_delayed;
+               return GPIO_RESULT_OK;
+       }
+
+       /* in any other modes, operate as normal GPIO */
+
+       return dal_hw_gpio_get_value(ptr, value);
+}
+
+static enum gpio_result set_config(
+       struct hw_gpio_pin *ptr,
+       const struct gpio_config_data *config_data)
+{
+       struct hw_hpd_dce110 *pin = HPD_DCE110_FROM_BASE(ptr);
+
+       if (!config_data)
+               return GPIO_RESULT_INVALID_DATA;
+
+       {
+               uint32_t value;
+
+               value = dm_read_reg(
+                       ptr->ctx,
+                       pin->addr.DC_HPD_TOGGLE_FILT_CNTL);
+
+               set_reg_field_value(
+                       value,
+                       config_data->config.hpd.delay_on_connect / 10,
+                       DC_HPD_TOGGLE_FILT_CNTL,
+                       DC_HPD_CONNECT_INT_DELAY);
+
+               set_reg_field_value(
+                       value,
+                       config_data->config.hpd.delay_on_disconnect / 10,
+                       DC_HPD_TOGGLE_FILT_CNTL,
+                       DC_HPD_DISCONNECT_INT_DELAY);
+
+               dm_write_reg(
+                       ptr->ctx,
+                       pin->addr.DC_HPD_TOGGLE_FILT_CNTL,
+                       value);
+
+       }
+
+       return GPIO_RESULT_OK;
+}
+
+static const struct hw_gpio_pin_funcs funcs = {
+       .destroy = destroy,
+       .open = dal_hw_gpio_open,
+       .get_value = get_value,
+       .set_value = dal_hw_gpio_set_value,
+       .set_config = set_config,
+       .change_mode = dal_hw_gpio_change_mode,
+       .close = dal_hw_gpio_close,
+};
+
+static bool construct(
+       struct hw_hpd_dce110 *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx)
+{
+       const struct hw_gpio_generic_dce110_init *init;
+
+       if (id != GPIO_ID_HPD) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       if ((en < GPIO_HPD_MIN) || (en > GPIO_HPD_MAX)) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       if (!dal_hw_hpd_construct(&pin->base, id, en, ctx)) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       pin->base.base.base.funcs = &funcs;
+
+       init = hw_gpio_generic_dce110_init + en;
+
+       pin->base.base.pin_reg = init->hw_gpio_data_reg;
+
+       pin->addr = init->addr;
+
+       return true;
+}
+
+struct hw_gpio_pin *dal_hw_hpd_dce110_create(
+       struct dc_context *ctx,
+       enum gpio_id id,
+       uint32_t en)
+{
+       struct hw_hpd_dce110 *pin = dm_alloc(ctx, sizeof(struct hw_hpd_dce110));
+
+       if (!pin) {
+               ASSERT_CRITICAL(false);
+               return NULL;
+       }
+
+       if (construct(pin, id, en, ctx))
+               return &pin->base.base.base;
+
+       ASSERT_CRITICAL(false);
+
+       dm_free(ctx, pin);
+
+       return NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.h
new file mode 100644
index 000000000000..d032f4b9c91e
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_hpd_dce110.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_HPD_DCE110_H__
+#define __DAL_HW_HPD_DCE110_H__
+
+struct hw_hpd_dce110_addr {
+       uint32_t DC_HPD_INT_STATUS;
+       uint32_t DC_HPD_TOGGLE_FILT_CNTL;
+};
+
+struct hw_hpd_dce110 {
+       struct hw_hpd base;
+       struct hw_hpd_dce110_addr addr;
+};
+
+#define HPD_DCE110_FROM_BASE(hpd_base) \
+       container_of((HW_HPD_FROM_BASE(hpd_base)), struct hw_hpd_dce110, base)
+
+struct hw_gpio_pin *dal_hw_hpd_dce110_create(
+       struct dc_context *ctx,
+       enum gpio_id id,
+       uint32_t en);
+
+#endif /*__DAL_HW_HPD_DCE110_H__*/
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.c
new file mode 100644
index 000000000000..b058f4d22708
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright 2013-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+
+#include "dm_services.h"
+#include "include/gpio_types.h"
+#include "../hw_translate.h"
+
+/*
+ * Header of this unit
+ */
+#include "hw_translate_dce110.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+/*
+ * This unit
+ */
+
+#include "../hw_gpio_pin.h"
+
+#include "dce/dce_11_0_d.h"
+#include "dce/dce_11_0_sh_mask.h"
+
+static bool offset_to_id(
+       uint32_t offset,
+       uint32_t mask,
+       enum gpio_id *id,
+       uint32_t *en)
+{
+       switch (offset) {
+       /* GENERIC */
+       case mmDC_GPIO_GENERIC_A:
+               *id = GPIO_ID_GENERIC;
+               switch (mask) {
+               case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
+                       *en = GPIO_GENERIC_A;
+                       return true;
+               case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
+                       *en = GPIO_GENERIC_B;
+                       return true;
+               case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
+                       *en = GPIO_GENERIC_C;
+                       return true;
+               case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
+                       *en = GPIO_GENERIC_D;
+                       return true;
+               case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
+                       *en = GPIO_GENERIC_E;
+                       return true;
+               case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
+                       *en = GPIO_GENERIC_F;
+                       return true;
+               case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
+                       *en = GPIO_GENERIC_G;
+                       return true;
+               default:
+                       ASSERT_CRITICAL(false);
+                       return false;
+               }
+       break;
+       /* HPD */
+       case mmDC_GPIO_HPD_A:
+               *id = GPIO_ID_HPD;
+               switch (mask) {
+               case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
+                       *en = GPIO_HPD_1;
+                       return true;
+               case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
+                       *en = GPIO_HPD_2;
+                       return true;
+               case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
+                       *en = GPIO_HPD_3;
+                       return true;
+               case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
+                       *en = GPIO_HPD_4;
+                       return true;
+               case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
+                       *en = GPIO_HPD_5;
+                       return true;
+               case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
+                       *en = GPIO_HPD_6;
+                       return true;
+               default:
+                       ASSERT_CRITICAL(false);
+                       return false;
+               }
+       break;
+       /* SYNCA */
+       case mmDC_GPIO_SYNCA_A:
+               *id = GPIO_ID_SYNC;
+               switch (mask) {
+               case DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK:
+                       *en = GPIO_SYNC_HSYNC_A;
+                       return true;
+               case DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK:
+                       *en = GPIO_SYNC_VSYNC_A;
+                       return true;
+               default:
+                       ASSERT_CRITICAL(false);
+                       return false;
+               }
+       break;
+       /* mmDC_GPIO_GENLK_MASK */
+       case mmDC_GPIO_GENLK_A:
+               *id = GPIO_ID_GSL;
+               switch (mask) {
+               case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
+                       *en = GPIO_GSL_GENLOCK_CLOCK;
+                       return true;
+               case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
+                       *en = GPIO_GSL_GENLOCK_VSYNC;
+                       return true;
+               case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
+                       *en = GPIO_GSL_SWAPLOCK_A;
+                       return true;
+               case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
+                       *en = GPIO_GSL_SWAPLOCK_B;
+                       return true;
+               default:
+                       ASSERT_CRITICAL(false);
+                       return false;
+               }
+       break;
+       /* DDC */
+       /* we don't care about the GPIO_ID for DDC
+        * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
+        * directly in the create method */
+       case mmDC_GPIO_DDC1_A:
+               *en = GPIO_DDC_LINE_DDC1;
+               return true;
+       case mmDC_GPIO_DDC2_A:
+               *en = GPIO_DDC_LINE_DDC2;
+               return true;
+       case mmDC_GPIO_DDC3_A:
+               *en = GPIO_DDC_LINE_DDC3;
+               return true;
+       case mmDC_GPIO_DDC4_A:
+               *en = GPIO_DDC_LINE_DDC4;
+               return true;
+       case mmDC_GPIO_DDC5_A:
+               *en = GPIO_DDC_LINE_DDC5;
+               return true;
+       case mmDC_GPIO_DDC6_A:
+               *en = GPIO_DDC_LINE_DDC6;
+               return true;
+       case mmDC_GPIO_DDCVGA_A:
+               *en = GPIO_DDC_LINE_DDC_VGA;
+               return true;
+       /* GPIO_I2CPAD */
+       case mmDC_GPIO_I2CPAD_A:
+               *en = GPIO_DDC_LINE_I2C_PAD;
+               return true;
+       /* Not implemented */
+       case mmDC_GPIO_PWRSEQ_A:
+       case mmDC_GPIO_PAD_STRENGTH_1:
+       case mmDC_GPIO_PAD_STRENGTH_2:
+       case mmDC_GPIO_DEBUG:
+               return false;
+       /* UNEXPECTED */
+       default:
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+}
+
+static bool id_to_offset(
+       enum gpio_id id,
+       uint32_t en,
+       struct gpio_pin_info *info)
+{
+       bool result = true;
+
+       switch (id) {
+       case GPIO_ID_DDC_DATA:
+               info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
+               switch (en) {
+               case GPIO_DDC_LINE_DDC1:
+                       info->offset = mmDC_GPIO_DDC1_A;
+               break;
+               case GPIO_DDC_LINE_DDC2:
+                       info->offset = mmDC_GPIO_DDC2_A;
+               break;
+               case GPIO_DDC_LINE_DDC3:
+                       info->offset = mmDC_GPIO_DDC3_A;
+               break;
+               case GPIO_DDC_LINE_DDC4:
+                       info->offset = mmDC_GPIO_DDC4_A;
+               break;
+               case GPIO_DDC_LINE_DDC5:
+                       info->offset = mmDC_GPIO_DDC5_A;
+               break;
+               case GPIO_DDC_LINE_DDC6:
+                       info->offset = mmDC_GPIO_DDC6_A;
+               break;
+               case GPIO_DDC_LINE_DDC_VGA:
+                       info->offset = mmDC_GPIO_DDCVGA_A;
+               break;
+               case GPIO_DDC_LINE_I2C_PAD:
+                       info->offset = mmDC_GPIO_I2CPAD_A;
+               break;
+               default:
+                       ASSERT_CRITICAL(false);
+                       result = false;
+               }
+       break;
+       case GPIO_ID_DDC_CLOCK:
+               info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK;
+               switch (en) {
+               case GPIO_DDC_LINE_DDC1:
+                       info->offset = mmDC_GPIO_DDC1_A;
+               break;
+               case GPIO_DDC_LINE_DDC2:
+                       info->offset = mmDC_GPIO_DDC2_A;
+               break;
+               case GPIO_DDC_LINE_DDC3:
+                       info->offset = mmDC_GPIO_DDC3_A;
+               break;
+               case GPIO_DDC_LINE_DDC4:
+                       info->offset = mmDC_GPIO_DDC4_A;
+               break;
+               case GPIO_DDC_LINE_DDC5:
+                       info->offset = mmDC_GPIO_DDC5_A;
+               break;
+               case GPIO_DDC_LINE_DDC6:
+                       info->offset = mmDC_GPIO_DDC6_A;
+               break;
+               case GPIO_DDC_LINE_DDC_VGA:
+                       info->offset = mmDC_GPIO_DDCVGA_A;
+               break;
+               case GPIO_DDC_LINE_I2C_PAD:
+                       info->offset = mmDC_GPIO_I2CPAD_A;
+               break;
+               default:
+                       ASSERT_CRITICAL(false);
+                       result = false;
+               }
+       break;
+       case GPIO_ID_GENERIC:
+               info->offset = mmDC_GPIO_GENERIC_A;
+               switch (en) {
+               case GPIO_GENERIC_A:
+                       info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
+               break;
+               case GPIO_GENERIC_B:
+                       info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
+               break;
+               case GPIO_GENERIC_C:
+                       info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
+               break;
+               case GPIO_GENERIC_D:
+                       info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
+               break;
+               case GPIO_GENERIC_E:
+                       info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
+               break;
+               case GPIO_GENERIC_F:
+                       info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
+               break;
+               case GPIO_GENERIC_G:
+                       info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
+               break;
+               default:
+                       ASSERT_CRITICAL(false);
+                       result = false;
+               }
+       break;
+       case GPIO_ID_HPD:
+               info->offset = mmDC_GPIO_HPD_A;
+               switch (en) {
+               case GPIO_HPD_1:
+                       info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
+               break;
+               case GPIO_HPD_2:
+                       info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
+               break;
+               case GPIO_HPD_3:
+                       info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
+               break;
+               case GPIO_HPD_4:
+                       info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
+               break;
+               case GPIO_HPD_5:
+                       info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
+               break;
+               case GPIO_HPD_6:
+                       info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
+               break;
+               default:
+                       ASSERT_CRITICAL(false);
+                       result = false;
+               }
+       break;
+       case GPIO_ID_SYNC:
+               switch (en) {
+               case GPIO_SYNC_HSYNC_A:
+                       info->offset = mmDC_GPIO_SYNCA_A;
+                       info->mask = DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK;
+               break;
+               case GPIO_SYNC_VSYNC_A:
+                       info->offset = mmDC_GPIO_SYNCA_A;
+                       info->mask = DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK;
+               break;
+               case GPIO_SYNC_HSYNC_B:
+               case GPIO_SYNC_VSYNC_B:
+               default:
+                       ASSERT_CRITICAL(false);
+                       result = false;
+               }
+       break;
+       case GPIO_ID_GSL:
+               switch (en) {
+               case GPIO_GSL_GENLOCK_CLOCK:
+                       info->offset = mmDC_GPIO_GENLK_A;
+                       info->mask = DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK;
+               break;
+               case GPIO_GSL_GENLOCK_VSYNC:
+                       info->offset = mmDC_GPIO_GENLK_A;
+                       info->mask =
+                               DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK;
+               break;
+               case GPIO_GSL_SWAPLOCK_A:
+                       info->offset = mmDC_GPIO_GENLK_A;
+                       info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK;
+               break;
+               case GPIO_GSL_SWAPLOCK_B:
+                       info->offset = mmDC_GPIO_GENLK_A;
+                       info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK;
+               break;
+               default:
+                       ASSERT_CRITICAL(false);
+                       result = false;
+               }
+       break;
+       case GPIO_ID_VIP_PAD:
+       default:
+               ASSERT_CRITICAL(false);
+               result = false;
+       }
+
+       if (result) {
+               info->offset_y = info->offset + 2;
+               info->offset_en = info->offset + 1;
+               info->offset_mask = info->offset - 1;
+
+               info->mask_y = info->mask;
+               info->mask_en = info->mask;
+               info->mask_mask = info->mask;
+       }
+
+       return result;
+}
+
+/* function table */
+static const struct hw_translate_funcs funcs = {
+       .offset_to_id = offset_to_id,
+       .id_to_offset = id_to_offset,
+};
+
+/*
+ * dal_hw_translate_dce110_init
+ *
+ * @brief
+ * Initialize Hw translate function pointers.
+ *
+ * @param
+ * struct hw_translate *tr - [out] struct of function pointers
+ *
+ */
+void dal_hw_translate_dce110_init(struct hw_translate *tr)
+{
+       tr->funcs = &funcs;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.h
new file mode 100644
index 000000000000..4d16e09853c8
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/dce110/hw_translate_dce110.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_TRANSLATE_DCE110_H__
+#define __DAL_HW_TRANSLATE_DCE110_H__
+
+struct hw_translate;
+
+/* Initialize Hw translate function pointers */
+void dal_hw_translate_dce110_init(struct hw_translate *tr);
+
+#endif /* __DAL_HW_TRANSLATE_DCE110_H__ */
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/ddc.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/ddc.c
new file mode 100644
index 000000000000..c3d8cdb44756
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/ddc.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+
+#include "dm_services.h"
+
+#include "include/gpio_interface.h"
+#include "include/ddc_interface.h"
+#include "include/gpio_service_interface.h"
+#include "hw_gpio_pin.h"
+#include "hw_translate.h"
+#include "hw_factory.h"
+#include "gpio_service.h"
+#include "gpio.h"
+
+/*
+ * Header of this unit
+ */
+
+#include "ddc.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+/*
+ * This unit
+ */
+
+enum gpio_result dal_ddc_open(
+       struct ddc *ddc,
+       enum gpio_mode mode,
+       enum gpio_ddc_config_type config_type)
+{
+       enum gpio_result result;
+
+       struct gpio_ddc_open_options data_options;
+       struct gpio_ddc_open_options clock_options;
+       struct gpio_config_data config_data;
+
+       result = dal_gpio_open_ex(ddc->pin_data, mode, &data_options);
+
+       if (result != GPIO_RESULT_OK) {
+               BREAK_TO_DEBUGGER();
+               return result;
+       }
+
+       result = dal_gpio_open_ex(ddc->pin_clock, mode, &clock_options);
+
+       if (result != GPIO_RESULT_OK) {
+               BREAK_TO_DEBUGGER();
+               goto failure;
+       }
+
+       /* DDC clock and data pins should belong
+        * to the same DDC block id,
+        * we use the data pin to set the pad mode. */
+
+       if (mode == GPIO_MODE_INPUT)
+               /* this is from detect_sink_type,
+                * we need extra delay there */
+               config_data.type = GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE;
+       else
+               config_data.type = GPIO_CONFIG_TYPE_DDC;
+
+       config_data.config.ddc.type = config_type;
+       config_data.config.ddc.data_en_bit_present =
+               data_options.en_bit_present;
+       config_data.config.ddc.clock_en_bit_present =
+               clock_options.en_bit_present;
+
+       result = dal_gpio_set_config(ddc->pin_data, &config_data);
+
+       if (result == GPIO_RESULT_OK)
+               return result;
+
+       BREAK_TO_DEBUGGER();
+
+       dal_gpio_close(ddc->pin_clock);
+
+failure:
+       dal_gpio_close(ddc->pin_data);
+
+       return result;
+}
+
+enum gpio_result dal_ddc_get_clock(
+       const struct ddc *ddc,
+       uint32_t *value)
+{
+       return dal_gpio_get_value(ddc->pin_clock, value);
+}
+
+enum gpio_result dal_ddc_set_clock(
+       const struct ddc *ddc,
+       uint32_t value)
+{
+       return dal_gpio_set_value(ddc->pin_clock, value);
+}
+
+enum gpio_result dal_ddc_get_data(
+       const struct ddc *ddc,
+       uint32_t *value)
+{
+       return dal_gpio_get_value(ddc->pin_data, value);
+}
+
+enum gpio_result dal_ddc_set_data(
+       const struct ddc *ddc,
+       uint32_t value)
+{
+       return dal_gpio_set_value(ddc->pin_data, value);
+}
+
+enum gpio_result dal_ddc_change_mode(
+       struct ddc *ddc,
+       enum gpio_mode mode)
+{
+       enum gpio_result result;
+
+       enum gpio_mode original_mode =
+               dal_gpio_get_mode(ddc->pin_data);
+
+       result = dal_gpio_change_mode(ddc->pin_data, mode);
+
+       /* [anaumov] DAL2 code returns GPIO_RESULT_NON_SPECIFIC_ERROR
+        * in case of failures;
+        * set_mode() is so that, in case of failure,
+        * we must explicitly set original mode */
+
+       if (result != GPIO_RESULT_OK)
+               goto failure;
+
+       result = dal_gpio_change_mode(ddc->pin_clock, mode);
+
+       if (result == GPIO_RESULT_OK)
+               return result;
+
+       dal_gpio_change_mode(ddc->pin_clock, original_mode);
+
+failure:
+       dal_gpio_change_mode(ddc->pin_data, original_mode);
+
+       return result;
+}
+
+bool dal_ddc_is_hw_supported(
+       const struct ddc *ddc)
+{
+       return ddc->hw_info.hw_supported;
+}
+
+enum gpio_ddc_line dal_ddc_get_line(
+       const struct ddc *ddc)
+{
+       return (enum gpio_ddc_line)dal_gpio_get_enum(ddc->pin_data);
+}
+
+bool dal_ddc_check_line_aborted(
+       const struct ddc *self)
+{
+       /* No arbitration with VBIOS is performed since DCE 6.0 */
+
+       return false;
+}
+
+enum gpio_result dal_ddc_set_config(
+       struct ddc *ddc,
+       enum gpio_ddc_config_type config_type)
+{
+       struct gpio_config_data config_data;
+
+       config_data.type = GPIO_CONFIG_TYPE_DDC;
+
+       config_data.config.ddc.type = config_type;
+       config_data.config.ddc.data_en_bit_present = false;
+       config_data.config.ddc.clock_en_bit_present = false;
+
+       return dal_gpio_set_config(ddc->pin_data, &config_data);
+}
+
+void dal_ddc_close(
+       struct ddc *ddc)
+{
+       dal_gpio_close(ddc->pin_clock);
+       dal_gpio_close(ddc->pin_data);
+}
+
+/*
+ * @brief
+ * Creation and destruction
+ */
+
+struct ddc *dal_gpio_create_ddc(
+       struct gpio_service *service,
+       uint32_t offset,
+       uint32_t mask,
+       struct gpio_ddc_hw_info *info)
+{
+       enum gpio_id id;
+       uint32_t en;
+       struct ddc *ddc;
+
+       if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en))
+               return NULL;
+
+       ddc = dm_alloc(service->ctx, sizeof(struct ddc));
+
+       if (!ddc) {
+               BREAK_TO_DEBUGGER();
+               return NULL;
+       }
+
+       ddc->pin_data = dal_gpio_service_create_gpio_ex(
+               service, GPIO_ID_DDC_DATA, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
+
+       if (!ddc->pin_data) {
+               BREAK_TO_DEBUGGER();
+               goto failure_1;
+       }
+
+       ddc->pin_clock = dal_gpio_service_create_gpio_ex(
+               service, GPIO_ID_DDC_CLOCK, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
+
+       if (!ddc->pin_clock) {
+               BREAK_TO_DEBUGGER();
+               goto failure_2;
+       }
+
+       ddc->hw_info = *info;
+
+       ddc->ctx = service->ctx;
+
+       return ddc;
+
+failure_2:
+       dal_gpio_service_destroy_gpio(&ddc->pin_data);
+
+failure_1:
+       dm_free(service->ctx, ddc);
+
+       return NULL;
+}
+
+static void destruct(struct ddc *ddc)
+{
+       dal_ddc_close(ddc);
+       dal_gpio_service_destroy_gpio(&ddc->pin_data);
+       dal_gpio_service_destroy_gpio(&ddc->pin_clock);
+
+}
+
+void dal_gpio_destroy_ddc(
+       struct ddc **ddc)
+{
+       if (!ddc || !*ddc) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
+       destruct(*ddc);
+       dm_free((*ddc)->ctx, *ddc);
+
+       *ddc = NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/ddc.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/ddc.h
new file mode 100644
index 000000000000..2631571f09c0
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/ddc.h
@@ -0,0 +1,45 @@
+/*
+ * 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_DDC_H__
+#define __DAL_DDC_H__
+
+struct ddc {
+       struct gpio *pin_data;
+       struct gpio *pin_clock;
+       struct gpio_ddc_hw_info hw_info;
+       struct dc_context *ctx;
+};
+
+struct ddc *dal_gpio_create_ddc(
+       struct gpio_service *service,
+       uint32_t offset,
+       uint32_t mask,
+       struct gpio_ddc_hw_info *info);
+
+void dal_gpio_destroy_ddc(
+       struct ddc **ddc);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_ddc_diag.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_ddc_diag.c
new file mode 100644
index 000000000000..1dd31d86031c
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_ddc_diag.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2012-16 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+#include "include/gpio_types.h"
+#include "../hw_gpio_pin.h"
+#include "../hw_gpio.h"
+#include "../hw_ddc.h"
+
+/*
+ * This unit
+ */
+static void destruct(
+       struct hw_ddc *pin)
+{
+       dal_hw_ddc_destruct(pin);
+}
+
+static void destroy(
+       struct hw_gpio_pin **ptr)
+{
+       struct hw_ddc *pin = HW_DDC_FROM_BASE(*ptr);
+
+       destruct(pin);
+
+       dm_free((*ptr)->ctx, pin);
+
+       *ptr = NULL;
+}
+
+static const struct hw_gpio_pin_funcs funcs = {
+       .destroy = destroy,
+       .open = NULL,
+       .get_value = NULL,
+       .set_value = NULL,
+       .set_config = NULL,
+       .change_mode = NULL,
+       .close = NULL,
+};
+
+static bool construct(
+       struct hw_ddc *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx)
+{
+       pin->base.base.funcs = &funcs;
+       return true;
+}
+
+struct hw_gpio_pin *dal_hw_ddc_diag_fpga_create(
+       struct dc_context *ctx,
+       enum gpio_id id,
+       uint32_t en)
+{
+       struct hw_ddc *pin = dm_alloc(ctx, sizeof(struct hw_ddc));
+
+       if (!pin) {
+               ASSERT_CRITICAL(false);
+               return NULL;
+       }
+
+       if (construct(pin, id, en, ctx))
+               return &pin->base.base;
+
+       ASSERT_CRITICAL(false);
+
+       dm_free(ctx, pin);
+
+       return NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_ddc_diag.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_ddc_diag.h
new file mode 100644
index 000000000000..7515aaf33ee3
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_ddc_diag.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2012-16 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_DDC_DIAG_FPGA_H__
+#define __DAL_HW_DDC_DIAG_FPGA_H__
+
+struct hw_gpio_pin *dal_hw_ddc_diag_fpga_create(
+       struct dc_context *ctx,
+       enum gpio_id id,
+       uint32_t en);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_factory_diag.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_factory_diag.c
new file mode 100644
index 000000000000..0690b4266002
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_factory_diag.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013-16 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+
+#include "dm_services.h"
+#include "include/gpio_types.h"
+#include "../hw_factory.h"
+
+/*
+ * Header of this unit
+ */
+
+#include "../hw_gpio_pin.h"
+#include "../hw_gpio.h"
+#include "../hw_ddc.h"
+#include "../hw_hpd.h"
+
+/* function table */
+static const struct hw_factory_funcs funcs = {
+       .create_ddc_data = NULL,
+       .create_ddc_clock = NULL,
+       .create_generic = NULL,
+       .create_hpd = NULL,
+       .create_gpio_pad = NULL,
+       .create_sync = NULL,
+       .create_gsl = NULL,
+};
+
+void dal_hw_factory_diag_fpga_init(struct hw_factory *factory)
+{
+       factory->number_of_pins[GPIO_ID_DDC_DATA] = 8;
+       factory->number_of_pins[GPIO_ID_DDC_CLOCK] = 8;
+       factory->number_of_pins[GPIO_ID_GENERIC] = 7;
+       factory->number_of_pins[GPIO_ID_HPD] = 6;
+       factory->number_of_pins[GPIO_ID_GPIO_PAD] = 31;
+       factory->number_of_pins[GPIO_ID_VIP_PAD] = 0;
+       factory->number_of_pins[GPIO_ID_SYNC] = 2;
+       factory->number_of_pins[GPIO_ID_GSL] = 4;
+       factory->funcs = &funcs;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_factory_diag.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_factory_diag.h
new file mode 100644
index 000000000000..8a74f6adb8ee
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_factory_diag.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2013-16 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_FACTORY_DIAG_FPGA_H__
+#define __DAL_HW_FACTORY_DIAG_FPGA_H__
+
+/* Initialize HW factory function pointers and pin info */
+void dal_hw_factory_diag_fpga_init(struct hw_factory *factory);
+
+#endif /* __DAL_HW_FACTORY_DIAG_FPGA_H__ */
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_hpd_diag.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_hpd_diag.c
new file mode 100644
index 000000000000..019e810ec31e
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_hpd_diag.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2012-16 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+#include "include/gpio_types.h"
+#include "../hw_gpio_pin.h"
+#include "../hw_gpio.h"
+#include "../hw_hpd.h"
+
+
+static void destruct(
+       struct hw_hpd *pin)
+{
+       dal_hw_hpd_destruct(pin);
+}
+
+static void destroy(
+       struct hw_gpio_pin **ptr)
+{
+       struct hw_hpd *pin = HW_HPD_FROM_BASE(*ptr);
+
+       destruct(pin);
+
+       dm_free((*ptr)->ctx, pin);
+
+       *ptr = NULL;
+}
+
+static const struct hw_gpio_pin_funcs funcs = {
+       .destroy = destroy,
+       .open = NULL,
+       .get_value = NULL,
+       .set_value = NULL,
+       .set_config = NULL,
+       .change_mode = NULL,
+       .close = NULL,
+};
+
+static bool construct(
+       struct hw_hpd *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx)
+{
+       if (!dal_hw_hpd_construct(pin, id, en, ctx)) {
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+
+       pin->base.base.funcs = &funcs;
+
+       return true;
+}
+
+struct hw_gpio_pin *dal_hw_hpd_diag_fpga_create(
+       struct dc_context *ctx,
+       enum gpio_id id,
+       uint32_t en)
+{
+       struct hw_hpd *pin = dm_alloc(ctx, sizeof(struct hw_hpd));
+
+       if (!pin) {
+               ASSERT_CRITICAL(false);
+               return NULL;
+       }
+
+       if (construct(pin, id, en, ctx))
+               return &pin->base.base;
+
+       ASSERT_CRITICAL(false);
+
+       dm_free(ctx, pin);
+
+       return NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_hpd_diag.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_hpd_diag.h
new file mode 100644
index 000000000000..bfa2c24a987a
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_hpd_diag.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2012-16 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_HPD_DIAG_FPGA_H__
+#define __DAL_HW_HPD_DIAG_FPGA_H__
+
+
+struct hw_gpio_pin *dal_hw_hpd_diag_fpga_create(
+       struct dc_context *ctx,
+       enum gpio_id id,
+       uint32_t en);
+
+#endif /*__DAL_HW_HPD_DIAG_FPGA_H__*/
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_translate_diag.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_translate_diag.c
new file mode 100644
index 000000000000..177330ab157c
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_translate_diag.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2013-16 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+#include "include/gpio_types.h"
+
+#include "../hw_translate.h"
+
+
+/* function table */
+static const struct hw_translate_funcs funcs = {
+       .offset_to_id = NULL,
+       .id_to_offset = NULL,
+};
+
+void dal_hw_translate_diag_fpga_init(struct hw_translate *tr)
+{
+       tr->funcs = &funcs;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_translate_diag.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_translate_diag.h
new file mode 100644
index 000000000000..4f053241fe96
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/diagnostics/hw_translate_diag.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013-16 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_TRANSLATE_DIAG_FPGA_H__
+#define __DAL_HW_TRANSLATE_DIAG_FPGA_H__
+
+struct hw_translate;
+
+/* Initialize Hw translate function pointers */
+void dal_hw_translate_diag_fpga_init(struct hw_translate *tr);
+
+#endif /* __DAL_HW_TRANSLATE_DIAG_FPGA_H__ */
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/gpio.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/gpio.h
new file mode 100644
index 000000000000..7fcbb6972895
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/gpio.h
@@ -0,0 +1,48 @@
+/*
+ * 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_GPIO_H__
+#define __DAL_GPIO_H__
+
+struct gpio {
+       struct gpio_service *service;
+       struct hw_gpio_pin *pin;
+       enum gpio_id id;
+       uint32_t en;
+       enum gpio_mode mode;
+       /* when GPIO comes from VBIOS, it has defined output state */
+       enum gpio_pin_output_state output_state;
+};
+
+struct gpio *dal_gpio_create(
+       struct gpio_service *service,
+       enum gpio_id id,
+       uint32_t en,
+       enum gpio_pin_output_state output_state);
+
+void dal_gpio_destroy(
+       struct gpio **ptr);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/gpio_base.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/gpio_base.c
new file mode 100644
index 000000000000..7e16d631e671
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/gpio_base.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+
+#include "dm_services.h"
+
+#include "include/gpio_interface.h"
+#include "include/gpio_service_interface.h"
+#include "hw_gpio_pin.h"
+#include "hw_translate.h"
+#include "hw_factory.h"
+#include "gpio_service.h"
+
+/*
+ * Header of this unit
+ */
+
+#include "gpio.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+/*
+ * This unit
+ */
+
+/*
+ * @brief
+ * Public API
+ */
+
+enum gpio_result dal_gpio_open(
+       struct gpio *gpio,
+       enum gpio_mode mode)
+{
+       return dal_gpio_open_ex(gpio, mode, NULL);
+}
+
+enum gpio_result dal_gpio_open_ex(
+       struct gpio *gpio,
+       enum gpio_mode mode,
+       void *options)
+{
+       if (gpio->pin) {
+               ASSERT_CRITICAL(false);
+               return GPIO_RESULT_ALREADY_OPENED;
+       }
+
+       gpio->mode = mode;
+
+       return dal_gpio_service_open(
+               gpio->service, gpio->id, gpio->en, mode, options, &gpio->pin);
+}
+
+enum gpio_result dal_gpio_get_value(
+       const struct gpio *gpio,
+       uint32_t *value)
+{
+       if (!gpio->pin) {
+               BREAK_TO_DEBUGGER();
+               return GPIO_RESULT_NULL_HANDLE;
+       }
+
+       return gpio->pin->funcs->get_value(gpio->pin, value);
+}
+
+enum gpio_result dal_gpio_set_value(
+       const struct gpio *gpio,
+       uint32_t value)
+{
+       if (!gpio->pin) {
+               BREAK_TO_DEBUGGER();
+               return GPIO_RESULT_NULL_HANDLE;
+       }
+
+       return gpio->pin->funcs->set_value(gpio->pin, value);
+}
+
+enum gpio_mode dal_gpio_get_mode(
+       const struct gpio *gpio)
+{
+       return gpio->mode;
+}
+
+enum gpio_result dal_gpio_change_mode(
+       struct gpio *gpio,
+       enum gpio_mode mode)
+{
+       if (!gpio->pin) {
+               BREAK_TO_DEBUGGER();
+               return GPIO_RESULT_NULL_HANDLE;
+       }
+
+       return gpio->pin->funcs->change_mode(gpio->pin, mode);
+}
+
+enum gpio_id dal_gpio_get_id(
+       const struct gpio *gpio)
+{
+       return gpio->id;
+}
+
+uint32_t dal_gpio_get_enum(
+       const struct gpio *gpio)
+{
+       return gpio->en;
+}
+
+enum gpio_result dal_gpio_set_config(
+       struct gpio *gpio,
+       const struct gpio_config_data *config_data)
+{
+       if (!gpio->pin) {
+               BREAK_TO_DEBUGGER();
+               return GPIO_RESULT_NULL_HANDLE;
+       }
+
+       return gpio->pin->funcs->set_config(gpio->pin, config_data);
+}
+
+enum gpio_result dal_gpio_get_pin_info(
+       const struct gpio *gpio,
+       struct gpio_pin_info *pin_info)
+{
+       return gpio->service->translate.funcs->id_to_offset(
+               gpio->id, gpio->en, pin_info) ?
+               GPIO_RESULT_OK : GPIO_RESULT_INVALID_DATA;
+}
+
+enum sync_source dal_gpio_get_sync_source(
+       const struct gpio *gpio)
+{
+       switch (gpio->id) {
+       case GPIO_ID_GENERIC:
+               switch (gpio->en) {
+               case GPIO_GENERIC_A:
+                       return SYNC_SOURCE_IO_GENERIC_A;
+               case GPIO_GENERIC_B:
+                       return SYNC_SOURCE_IO_GENERIC_B;
+               case GPIO_GENERIC_C:
+                       return SYNC_SOURCE_IO_GENERIC_C;
+               case GPIO_GENERIC_D:
+                       return SYNC_SOURCE_IO_GENERIC_D;
+               case GPIO_GENERIC_E:
+                       return SYNC_SOURCE_IO_GENERIC_E;
+               case GPIO_GENERIC_F:
+                       return SYNC_SOURCE_IO_GENERIC_F;
+               default:
+                       return SYNC_SOURCE_NONE;
+               }
+       break;
+       case GPIO_ID_SYNC:
+               switch (gpio->en) {
+               case GPIO_SYNC_HSYNC_A:
+                       return SYNC_SOURCE_IO_HSYNC_A;
+               case GPIO_SYNC_VSYNC_A:
+                       return SYNC_SOURCE_IO_VSYNC_A;
+               case GPIO_SYNC_HSYNC_B:
+                       return SYNC_SOURCE_IO_HSYNC_B;
+               case GPIO_SYNC_VSYNC_B:
+                       return SYNC_SOURCE_IO_VSYNC_B;
+               default:
+                       return SYNC_SOURCE_NONE;
+               }
+       break;
+       case GPIO_ID_HPD:
+               switch (gpio->en) {
+               case GPIO_HPD_1:
+                       return SYNC_SOURCE_IO_HPD1;
+               case GPIO_HPD_2:
+                       return SYNC_SOURCE_IO_HPD2;
+               default:
+                       return SYNC_SOURCE_NONE;
+               }
+       break;
+       case GPIO_ID_GSL:
+               switch (gpio->en) {
+               case GPIO_GSL_GENLOCK_CLOCK:
+                       return SYNC_SOURCE_GSL_IO_GENLOCK_CLOCK;
+               case GPIO_GSL_GENLOCK_VSYNC:
+                       return SYNC_SOURCE_GSL_IO_GENLOCK_VSYNC;
+               case GPIO_GSL_SWAPLOCK_A:
+                       return SYNC_SOURCE_GSL_IO_SWAPLOCK_A;
+               case GPIO_GSL_SWAPLOCK_B:
+                       return SYNC_SOURCE_GSL_IO_SWAPLOCK_B;
+               default:
+                       return SYNC_SOURCE_NONE;
+               }
+       break;
+       default:
+               return SYNC_SOURCE_NONE;
+       }
+}
+
+enum gpio_pin_output_state dal_gpio_get_output_state(
+       const struct gpio *gpio)
+{
+       return gpio->output_state;
+}
+
+void dal_gpio_close(
+       struct gpio *gpio)
+{
+       if (!gpio)
+               return;
+
+       dal_gpio_service_close(gpio->service, &gpio->pin);
+
+       gpio->mode = GPIO_MODE_UNKNOWN;
+}
+
+/*
+ * @brief
+ * Creation and destruction
+ */
+
+struct gpio *dal_gpio_create(
+       struct gpio_service *service,
+       enum gpio_id id,
+       uint32_t en,
+       enum gpio_pin_output_state output_state)
+{
+       struct gpio *gpio = dm_alloc(service->ctx, sizeof(struct gpio));
+
+       if (!gpio) {
+               ASSERT_CRITICAL(false);
+               return NULL;
+       }
+
+       gpio->service = service;
+       gpio->pin = NULL;
+       gpio->id = id;
+       gpio->en = en;
+       gpio->mode = GPIO_MODE_UNKNOWN;
+       gpio->output_state = output_state;
+
+       return gpio;
+}
+
+void dal_gpio_destroy(
+       struct gpio **gpio)
+{
+       if (!gpio || !*gpio) {
+               ASSERT_CRITICAL(false);
+               return;
+       }
+
+       dal_gpio_close(*gpio);
+
+       dm_free((*gpio)->service->ctx, *gpio);
+
+       *gpio = NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.c
new file mode 100644
index 000000000000..6837898b3bfe
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+
+#include "dm_services.h"
+#include "include/gpio_interface.h"
+#include "include/ddc_interface.h"
+#include "include/irq_interface.h"
+#include "include/gpio_service_interface.h"
+#include "hw_translate.h"
+#include "hw_factory.h"
+
+/*
+ * Header of this unit
+ */
+
+#include "gpio_service.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+#include "hw_gpio_pin.h"
+#include "gpio.h"
+#include "ddc.h"
+#include "irq.h"
+
+/*
+ * This unit
+ */
+
+/*
+ * @brief
+ * Public API.
+ */
+
+struct gpio_service *dal_gpio_service_create(
+       enum dce_version dce_version_major,
+       enum dce_version dce_version_minor,
+       struct dc_context *ctx)
+{
+       struct gpio_service *service;
+
+       uint32_t index_of_id;
+
+       service = dm_alloc(ctx, sizeof(struct gpio_service));
+
+       if (!service) {
+               BREAK_TO_DEBUGGER();
+               return NULL;
+       }
+
+       if (!dal_hw_translate_init(&service->translate, dce_version_major,
+                       dce_version_minor)) {
+               BREAK_TO_DEBUGGER();
+               goto failure_1;
+       }
+
+       if (!dal_hw_factory_init(&service->factory, dce_version_major,
+                       dce_version_minor)) {
+               BREAK_TO_DEBUGGER();
+               goto failure_1;
+       }
+
+       /* allocate and initialize business storage */
+       {
+               const uint32_t bits_per_uint = sizeof(uint32_t) << 3;
+
+               index_of_id = 0;
+               service->ctx = ctx;
+
+               do {
+                       uint32_t number_of_bits =
+                               service->factory.number_of_pins[index_of_id];
+
+                       uint32_t number_of_uints =
+                               (number_of_bits + bits_per_uint - 1) /
+                               bits_per_uint;
+
+                       uint32_t *slot;
+
+                       if (number_of_bits) {
+                               uint32_t index_of_uint = 0;
+
+                               slot = dm_alloc(
+                                       ctx,
+                                       number_of_uints * sizeof(uint32_t));
+
+                               if (!slot) {
+                                       BREAK_TO_DEBUGGER();
+                                       goto failure_2;
+                               }
+
+                               do {
+                                       slot[index_of_uint] = 0;
+
+                                       ++index_of_uint;
+                               } while (index_of_uint < number_of_uints);
+                       } else
+                               slot = NULL;
+
+                       service->busyness[index_of_id] = slot;
+
+                       ++index_of_id;
+               } while (index_of_id < GPIO_ID_COUNT);
+       }
+
+       return service;
+
+failure_2:
+       while (index_of_id) {
+               uint32_t *slot;
+
+               --index_of_id;
+
+               slot = service->busyness[index_of_id];
+
+               if (slot)
+                       dm_free(ctx, slot);
+       };
+
+failure_1:
+       dm_free(ctx, service);
+
+       return NULL;
+}
+
+struct gpio *dal_gpio_service_create_gpio(
+       struct gpio_service *service,
+       uint32_t offset,
+       uint32_t mask,
+       enum gpio_pin_output_state output_state)
+{
+       enum gpio_id id;
+       uint32_t en;
+
+       if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) {
+               BREAK_TO_DEBUGGER();
+               return NULL;
+       }
+
+       return dal_gpio_create(service, id, en, output_state);
+}
+
+struct gpio *dal_gpio_service_create_gpio_ex(
+       struct gpio_service *service,
+       enum gpio_id id,
+       uint32_t en,
+       enum gpio_pin_output_state output_state)
+{
+       return dal_gpio_create(service, id, en, output_state);
+}
+
+void dal_gpio_service_destroy_gpio(
+       struct gpio **gpio)
+{
+       dal_gpio_destroy(gpio);
+}
+
+struct ddc *dal_gpio_service_create_ddc(
+       struct gpio_service *service,
+       uint32_t offset,
+       uint32_t mask,
+       struct gpio_ddc_hw_info *info)
+{
+       return dal_gpio_create_ddc(service, offset, mask, info);
+}
+
+void dal_gpio_service_destroy_ddc(
+       struct ddc **ddc)
+{
+       dal_gpio_destroy_ddc(ddc);
+}
+
+struct irq *dal_gpio_service_create_irq(
+       struct gpio_service *service,
+       uint32_t offset,
+       uint32_t mask)
+{
+       enum gpio_id id;
+       uint32_t en;
+
+       if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) {
+               ASSERT_CRITICAL(false);
+               return NULL;
+       }
+
+       return dal_gpio_create_irq(service, id, en);
+}
+
+struct irq *dal_gpio_service_create_irq_ex(
+       struct gpio_service *service,
+       enum gpio_id id,
+       uint32_t en)
+{
+       return dal_gpio_create_irq(service, id, en);
+}
+
+void dal_gpio_service_destroy_irq(
+       struct irq **irq)
+{
+       dal_gpio_destroy_irq(irq);
+}
+
+void dal_gpio_service_destroy(
+       struct gpio_service **ptr)
+{
+       if (!ptr || !*ptr) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
+       /* free business storage */
+       {
+               uint32_t index_of_id = 0;
+
+               do {
+                       uint32_t *slot = (*ptr)->busyness[index_of_id];
+
+                       if (slot)
+                               dm_free((*ptr)->ctx, slot);
+
+                       ++index_of_id;
+               } while (index_of_id < GPIO_ID_COUNT);
+       }
+
+       dm_free((*ptr)->ctx, *ptr);
+
+       *ptr = NULL;
+}
+
+/*
+ * @brief
+ * Private API.
+ */
+
+static bool is_pin_busy(
+       const struct gpio_service *service,
+       enum gpio_id id,
+       uint32_t en)
+{
+       const uint32_t bits_per_uint = sizeof(uint32_t) << 3;
+
+       const uint32_t *slot = service->busyness[id] + (en / bits_per_uint);
+
+       return 0 != (*slot & (1 << (en % bits_per_uint)));
+}
+
+static void set_pin_busy(
+       struct gpio_service *service,
+       enum gpio_id id,
+       uint32_t en)
+{
+       const uint32_t bits_per_uint = sizeof(uint32_t) << 3;
+
+       service->busyness[id][en / bits_per_uint] |=
+               (1 << (en % bits_per_uint));
+}
+
+static void set_pin_free(
+       struct gpio_service *service,
+       enum gpio_id id,
+       uint32_t en)
+{
+       const uint32_t bits_per_uint = sizeof(uint32_t) << 3;
+
+       service->busyness[id][en / bits_per_uint] &=
+               ~(1 << (en % bits_per_uint));
+}
+
+enum gpio_result dal_gpio_service_open(
+       struct gpio_service *service,
+       enum gpio_id id,
+       uint32_t en,
+       enum gpio_mode mode,
+       void *options,
+       struct hw_gpio_pin **ptr)
+{
+       struct hw_gpio_pin *pin;
+
+       if (!service->busyness[id]) {
+               ASSERT_CRITICAL(false);
+               return GPIO_RESULT_OPEN_FAILED;
+       }
+
+       if (is_pin_busy(service, id, en)) {
+               ASSERT_CRITICAL(false);
+               return GPIO_RESULT_DEVICE_BUSY;
+       }
+
+       switch (id) {
+       case GPIO_ID_DDC_DATA:
+               pin = service->factory.funcs->create_ddc_data(
+                       service->ctx, id, en);
+       break;
+       case GPIO_ID_DDC_CLOCK:
+               pin = service->factory.funcs->create_ddc_clock(
+                       service->ctx, id, en);
+       break;
+       case GPIO_ID_GENERIC:
+               pin = service->factory.funcs->create_generic(
+                       service->ctx, id, en);
+       break;
+       case GPIO_ID_HPD:
+               pin = service->factory.funcs->create_hpd(
+                       service->ctx, id, en);
+       break;
+       case GPIO_ID_GPIO_PAD:
+               pin = service->factory.funcs->create_gpio_pad(
+                       service->ctx, id, en);
+       break;
+       case GPIO_ID_SYNC:
+               pin = service->factory.funcs->create_sync(
+                       service->ctx, id, en);
+       break;
+       case GPIO_ID_GSL:
+               pin = service->factory.funcs->create_gsl(
+                       service->ctx, id, en);
+       break;
+       default:
+               ASSERT_CRITICAL(false);
+               return GPIO_RESULT_NON_SPECIFIC_ERROR;
+       }
+
+       if (!pin) {
+               ASSERT_CRITICAL(false);
+               return GPIO_RESULT_NON_SPECIFIC_ERROR;
+       }
+
+       if (!pin->funcs->open(pin, mode, options)) {
+               ASSERT_CRITICAL(false);
+               dal_gpio_service_close(service, &pin);
+               return GPIO_RESULT_OPEN_FAILED;
+       }
+
+       set_pin_busy(service, id, en);
+       *ptr = pin;
+       return GPIO_RESULT_OK;
+}
+
+void dal_gpio_service_close(
+       struct gpio_service *service,
+       struct hw_gpio_pin **ptr)
+{
+       struct hw_gpio_pin *pin;
+
+       if (!ptr) {
+               ASSERT_CRITICAL(false);
+               return;
+       }
+
+       pin = *ptr;
+
+       if (pin) {
+               set_pin_free(service, pin->id, pin->en);
+
+               pin->funcs->close(pin);
+
+               pin->funcs->destroy(ptr);
+       }
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.h
new file mode 100644
index 000000000000..a17c4386668d
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/gpio_service.h
@@ -0,0 +1,57 @@
+/*
+ * 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_GPIO_SERVICE_H__
+#define __DAL_GPIO_SERVICE_H__
+
+struct hw_translate;
+struct hw_factory;
+
+struct gpio_service {
+       struct dc_context *ctx;
+       struct hw_translate translate;
+       struct hw_factory factory;
+       /*
+        * @brief
+        * Business storage.
+        * For each member of 'enum gpio_id',
+        * store array of bits (packed into uint32_t slots),
+        * index individual bit by 'en' value */
+       uint32_t *busyness[GPIO_ID_COUNT];
+};
+
+enum gpio_result dal_gpio_service_open(
+       struct gpio_service *service,
+       enum gpio_id id,
+       uint32_t en,
+       enum gpio_mode mode,
+       void *options,
+       struct hw_gpio_pin **ptr);
+
+void dal_gpio_service_close(
+       struct gpio_service *service,
+       struct hw_gpio_pin **ptr);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c
new file mode 100644
index 000000000000..41e46a7dc001
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+#include "include/gpio_types.h"
+#include "hw_gpio_pin.h"
+#include "hw_gpio.h"
+
+/*
+ * Header of this unit
+ */
+
+#include "hw_ddc.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+/*
+ * This unit
+ */
+
+#define FROM_HW_GPIO(ptr) \
+       container_of((ptr), struct hw_ddc, base)
+
+#define FROM_HW_GPIO_PIN(ptr) \
+       FROM_HW_GPIO(container_of((ptr), struct hw_gpio, base))
+
+bool dal_hw_ddc_open(
+       struct hw_gpio_pin *ptr,
+       enum gpio_mode mode,
+       void *options)
+{
+       struct hw_ddc *pin = FROM_HW_GPIO_PIN(ptr);
+
+       uint32_t en;
+
+       if (!options) {
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+
+       /* get the EN bit before overwriting it */
+
+       dal_hw_gpio_get_reg_value(
+               ptr->ctx,
+               &pin->base.pin_reg.DC_GPIO_DATA_EN,
+               &en);
+
+       ((struct gpio_ddc_open_options *)options)->en_bit_present = (en != 0);
+
+       return dal_hw_gpio_open(ptr, mode, options);
+}
+
+bool dal_hw_ddc_construct(
+       struct hw_ddc *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx)
+{
+       if (!dal_hw_gpio_construct(&pin->base, id, en, ctx))
+               return false;
+
+       pin->mask.DC_GPIO_DDC_MASK_MASK = 0;
+       pin->mask.DC_GPIO_DDC_PD_EN_MASK = 0;
+       pin->mask.DC_GPIO_DDC_RECV_MASK = 0;
+       pin->mask.AUX_PAD_MODE_MASK = 0;
+       pin->mask.AUX_POL_MASK = 0;
+       pin->mask.DC_GPIO_DDCCLK_STR_MASK = 0;
+
+       return true;
+}
+
+void dal_hw_ddc_destruct(
+       struct hw_ddc *pin)
+{
+       dal_hw_gpio_destruct(&pin->base);
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.h
new file mode 100644
index 000000000000..a3a727c58b83
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_ddc.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_DDC_H__
+#define __DAL_HW_DDC_H__
+
+struct hw_ddc_mask {
+       uint32_t DC_GPIO_DDC_MASK_MASK;
+       uint32_t DC_GPIO_DDC_PD_EN_MASK;
+       uint32_t DC_GPIO_DDC_RECV_MASK;
+       uint32_t AUX_PAD_MODE_MASK;
+       uint32_t AUX_POL_MASK;
+       uint32_t DC_GPIO_DDCCLK_STR_MASK;
+};
+
+struct hw_ddc {
+       struct hw_gpio base;
+       struct hw_ddc_mask mask;
+};
+
+#define HW_DDC_FROM_BASE(hw_gpio) \
+       container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_ddc, base)
+
+bool dal_hw_ddc_construct(
+       struct hw_ddc *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx);
+
+void dal_hw_ddc_destruct(
+       struct hw_ddc *pin);
+
+bool dal_hw_ddc_open(
+       struct hw_gpio_pin *ptr,
+       enum gpio_mode mode,
+       void *options);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c
new file mode 100644
index 000000000000..e0f6ecfaf4a7
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+#include "include/gpio_types.h"
+
+/*
+ * Header of this unit
+ */
+
+#include "hw_factory.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
+#include "dce110/hw_factory_dce110.h"
+#endif
+
+#include "diagnostics/hw_factory_diag.h"
+
+/*
+ * This unit
+ */
+
+bool dal_hw_factory_init(
+       struct hw_factory *factory,
+       enum dce_version dce_version,
+       enum dce_environment dce_environment)
+{
+       if (IS_FPGA_MAXIMUS_DC(dce_environment)) {
+               dal_hw_factory_diag_fpga_init(factory);
+               return true;
+       }
+
+       switch (dce_version) {
+
+#if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
+       case DCE_VERSION_10_0:
+               dal_hw_factory_dce110_init(factory);
+               return true;
+#endif
+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
+       case DCE_VERSION_11_0:
+               dal_hw_factory_dce110_init(factory);
+               return true;
+#endif
+       default:
+               ASSERT_CRITICAL(false);
+               return false;
+       }
+}
+
+void dal_hw_factory_destroy(
+       struct dc_context *ctx,
+       struct hw_factory **factory)
+{
+       if (!factory || !*factory) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
+       dm_free(ctx, *factory);
+
+       *factory = NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.h
new file mode 100644
index 000000000000..1fa8b6d85f35
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_factory.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_FACTORY_H__
+#define __DAL_HW_FACTORY_H__
+
+struct hw_gpio_pin;
+
+struct hw_factory {
+       uint32_t number_of_pins[GPIO_ID_COUNT];
+
+       const struct hw_factory_funcs {
+               struct hw_gpio_pin *(*create_ddc_data)(
+                       struct dc_context *ctx,
+                       enum gpio_id id,
+                       uint32_t en);
+               struct hw_gpio_pin *(*create_ddc_clock)(
+                       struct dc_context *ctx,
+                       enum gpio_id id,
+                       uint32_t en);
+               struct hw_gpio_pin *(*create_generic)(
+                       struct dc_context *ctx,
+                       enum gpio_id id,
+                       uint32_t en);
+               struct hw_gpio_pin *(*create_hpd)(
+                       struct dc_context *ctx,
+                       enum gpio_id id,
+                       uint32_t en);
+               struct hw_gpio_pin *(*create_gpio_pad)(
+                       struct dc_context *ctx,
+                       enum gpio_id id,
+                       uint32_t en);
+               struct hw_gpio_pin *(*create_sync)(
+                       struct dc_context *ctx,
+                       enum gpio_id id,
+                       uint32_t en);
+               struct hw_gpio_pin *(*create_gsl)(
+                       struct dc_context *ctx,
+                       enum gpio_id id,
+                       uint32_t en);
+       } *funcs;
+};
+
+bool dal_hw_factory_init(
+       struct hw_factory *factory,
+       enum dce_version dce_version,
+       enum dce_environment dce_environment);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.c
new file mode 100644
index 000000000000..2a2262c7b107
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+#include "include/gpio_types.h"
+#include "hw_gpio_pin.h"
+
+/*
+ * Header of this unit
+ */
+
+#include "hw_gpio.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+/*
+ * This unit
+ */
+
+enum gpio_result dal_hw_gpio_get_reg_value(
+       struct dc_context *ctx,
+       const struct addr_mask *reg,
+       uint32_t *value)
+{
+       *value = dm_read_reg(ctx, reg->addr);
+
+       *value &= reg->mask;
+
+       return GPIO_RESULT_OK;
+}
+
+enum gpio_result dal_hw_gpio_set_reg_value(
+       struct dc_context *ctx,
+       const struct addr_mask *reg,
+       uint32_t value)
+{
+       uint32_t prev_value;
+
+       if ((value & reg->mask) != value) {
+               BREAK_TO_DEBUGGER();
+               return GPIO_RESULT_INVALID_DATA;
+       }
+
+       prev_value = dm_read_reg(ctx, reg->addr);
+
+       prev_value &= ~reg->mask;
+       prev_value |= (value & reg->mask);
+
+       dm_write_reg(ctx, reg->addr, prev_value);
+
+       return GPIO_RESULT_OK;
+}
+
+uint32_t dal_hw_gpio_get_shift_from_mask(
+       uint32_t mask)
+{
+       uint32_t result = 0;
+
+       if (!mask)
+               return 32;
+
+       do {
+               if ((1 << result) & mask)
+                       break;
+
+               ++result;
+       } while (result < 32);
+
+       return result;
+}
+
+#define FROM_HW_GPIO_PIN(ptr) \
+       container_of((ptr), struct hw_gpio, base)
+
+static void store_registers(
+       struct hw_gpio *pin)
+{
+       dal_hw_gpio_get_reg_value(
+               pin->base.ctx,
+               &pin->pin_reg.DC_GPIO_DATA_MASK,
+               &pin->store.mask);
+       dal_hw_gpio_get_reg_value(
+               pin->base.ctx,
+               &pin->pin_reg.DC_GPIO_DATA_A,
+               &pin->store.a);
+       dal_hw_gpio_get_reg_value(
+               pin->base.ctx,
+               &pin->pin_reg.DC_GPIO_DATA_EN,
+               &pin->store.en);
+
+       if (pin->mux_supported)
+               dal_hw_gpio_get_reg_value(
+                       pin->base.ctx,
+                       &pin->mux_reg.GPIO_MUX_CONTROL,
+                       &pin->store.mux);
+}
+
+static void restore_registers(
+       struct hw_gpio *pin)
+{
+       dal_hw_gpio_set_reg_value(
+               pin->base.ctx,
+               &pin->pin_reg.DC_GPIO_DATA_MASK,
+               pin->store.mask);
+       dal_hw_gpio_set_reg_value(
+               pin->base.ctx,
+               &pin->pin_reg.DC_GPIO_DATA_A,
+               pin->store.a);
+       dal_hw_gpio_set_reg_value(
+               pin->base.ctx,
+               &pin->pin_reg.DC_GPIO_DATA_EN,
+               pin->store.en);
+
+       if (pin->mux_supported)
+               dal_hw_gpio_set_reg_value(
+                       pin->base.ctx,
+                       &pin->mux_reg.GPIO_MUX_CONTROL,
+                       pin->store.mux);
+}
+
+bool dal_hw_gpio_open(
+       struct hw_gpio_pin *ptr,
+       enum gpio_mode mode,
+       void *options)
+{
+       struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
+
+       store_registers(pin);
+
+       ptr->opened = (pin->funcs->config_mode(pin, mode) == GPIO_RESULT_OK);
+
+       return ptr->opened;
+}
+
+enum gpio_result dal_hw_gpio_get_value(
+       const struct hw_gpio_pin *ptr,
+       uint32_t *value)
+{
+       const struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
+
+       enum gpio_result result;
+
+       switch (ptr->mode) {
+       case GPIO_MODE_INPUT:
+       case GPIO_MODE_OUTPUT:
+       case GPIO_MODE_HARDWARE:
+       case GPIO_MODE_FAST_OUTPUT:
+               result = dal_hw_gpio_get_reg_value(
+                       ptr->ctx,
+                       &pin->pin_reg.DC_GPIO_DATA_Y,
+                       value);
+               /* Clients does not know that the value
+                * comes from register and is shifted. */
+               if (result == GPIO_RESULT_OK)
+                       *value >>= dal_hw_gpio_get_shift_from_mask(
+                               pin->pin_reg.DC_GPIO_DATA_Y.mask);
+       break;
+       default:
+               result = GPIO_RESULT_NON_SPECIFIC_ERROR;
+       }
+
+       return result;
+}
+
+enum gpio_result dal_hw_gpio_set_value(
+       const struct hw_gpio_pin *ptr,
+       uint32_t value)
+{
+       struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
+
+       /* This is the public interface
+        * where the input comes from client, not shifted yet
+        * (because client does not know the shifts). */
+
+       switch (ptr->mode) {
+       case GPIO_MODE_OUTPUT:
+               return dal_hw_gpio_set_reg_value(
+                       ptr->ctx,
+                       &pin->pin_reg.DC_GPIO_DATA_A,
+                       value << dal_hw_gpio_get_shift_from_mask(
+                               pin->pin_reg.DC_GPIO_DATA_A.mask));
+       case GPIO_MODE_FAST_OUTPUT:
+               /* We use (EN) to faster switch (used in DDC GPIO).
+                * So (A) is grounded, output is driven by (EN = 0)
+                * to pull the line down (output == 0) and (EN=1)
+                * then output is tri-state */
+               return dal_hw_gpio_set_reg_value(
+                       ptr->ctx,
+                       &pin->pin_reg.DC_GPIO_DATA_EN,
+                       pin->pin_reg.DC_GPIO_DATA_EN.mask &
+                       ~(value << dal_hw_gpio_get_shift_from_mask(
+                               pin->pin_reg.DC_GPIO_DATA_EN.mask)));
+       default:
+               return GPIO_RESULT_NON_SPECIFIC_ERROR;
+       }
+}
+
+enum gpio_result dal_hw_gpio_change_mode(
+       struct hw_gpio_pin *ptr,
+       enum gpio_mode mode)
+{
+       struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
+
+       return pin->funcs->config_mode(pin, mode);
+}
+
+void dal_hw_gpio_close(
+       struct hw_gpio_pin *ptr)
+{
+       struct hw_gpio *pin = FROM_HW_GPIO_PIN(ptr);
+
+       restore_registers(pin);
+
+       ptr->mode = GPIO_MODE_UNKNOWN;
+       ptr->opened = false;
+}
+
+static enum gpio_result config_mode_input(
+       struct hw_gpio *pin)
+{
+       enum gpio_result result;
+
+       /* turn off output enable, act as input pin;
+        * program the pin as GPIO, mask out signal driven by HW */
+
+       result = dal_hw_gpio_set_reg_value(
+               pin->base.ctx,
+               &pin->pin_reg.DC_GPIO_DATA_EN,
+               0);
+
+       if (result != GPIO_RESULT_OK)
+               return GPIO_RESULT_NON_SPECIFIC_ERROR;
+
+       result = dal_hw_gpio_set_reg_value(
+               pin->base.ctx,
+               &pin->pin_reg.DC_GPIO_DATA_MASK,
+               pin->pin_reg.DC_GPIO_DATA_MASK.mask);
+
+       if (result != GPIO_RESULT_OK)
+               return GPIO_RESULT_NON_SPECIFIC_ERROR;
+
+       return GPIO_RESULT_OK;
+}
+
+static enum gpio_result config_mode_output(
+       struct hw_gpio *pin)
+{
+       enum gpio_result result;
+
+       /* turn on output enable, act as output pin;
+        * program the pin as GPIO, mask out signal driven by HW */
+
+       result = dal_hw_gpio_set_reg_value(
+               pin->base.ctx,
+               &pin->pin_reg.DC_GPIO_DATA_EN,
+               pin->pin_reg.DC_GPIO_DATA_EN.mask);
+
+       if (result != GPIO_RESULT_OK)
+               return GPIO_RESULT_NON_SPECIFIC_ERROR;
+
+       result = dal_hw_gpio_set_reg_value(
+               pin->base.ctx,
+               &pin->pin_reg.DC_GPIO_DATA_MASK,
+               pin->pin_reg.DC_GPIO_DATA_MASK.mask);
+
+       if (result != GPIO_RESULT_OK)
+               return GPIO_RESULT_NON_SPECIFIC_ERROR;
+
+       return GPIO_RESULT_OK;
+}
+
+static enum gpio_result config_mode_fast_output(
+       struct hw_gpio *pin)
+{
+       enum gpio_result result;
+
+       /* grounding the A register then use the EN register bit
+        * will have faster effect on the rise time */
+
+       result = dal_hw_gpio_set_reg_value(
+               pin->base.ctx,
+               &pin->pin_reg.DC_GPIO_DATA_A, 0);
+
+       if (result != GPIO_RESULT_OK)
+               return GPIO_RESULT_NON_SPECIFIC_ERROR;
+
+       result = dal_hw_gpio_set_reg_value(
+               pin->base.ctx,
+               &pin->pin_reg.DC_GPIO_DATA_MASK,
+               pin->pin_reg.DC_GPIO_DATA_MASK.mask);
+
+       if (result != GPIO_RESULT_OK)
+               return GPIO_RESULT_NON_SPECIFIC_ERROR;
+
+       return GPIO_RESULT_OK;
+}
+
+static enum gpio_result config_mode_hardware(
+       struct hw_gpio *pin)
+{
+       /* program the pin as tri-state, pin is driven by HW */
+
+       enum gpio_result result =
+               dal_hw_gpio_set_reg_value(
+                       pin->base.ctx,
+                       &pin->pin_reg.DC_GPIO_DATA_MASK,
+                       0);
+
+       if (result != GPIO_RESULT_OK)
+               return GPIO_RESULT_NON_SPECIFIC_ERROR;
+
+       return GPIO_RESULT_OK;
+}
+
+enum gpio_result dal_hw_gpio_config_mode(
+       struct hw_gpio *pin,
+       enum gpio_mode mode)
+{
+       pin->base.mode = mode;
+
+       switch (mode) {
+       case GPIO_MODE_INPUT:
+               return config_mode_input(pin);
+       case GPIO_MODE_OUTPUT:
+               return config_mode_output(pin);
+       case GPIO_MODE_FAST_OUTPUT:
+               return config_mode_fast_output(pin);
+       case GPIO_MODE_HARDWARE:
+               return config_mode_hardware(pin);
+       default:
+               return GPIO_RESULT_NON_SPECIFIC_ERROR;
+       }
+}
+
+const struct hw_gpio_funcs func = {
+       .config_mode = dal_hw_gpio_config_mode,
+};
+
+bool dal_hw_gpio_construct(
+       struct hw_gpio *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx)
+{
+       struct hw_gpio_pin *base = &pin->base;
+
+       if (!dal_hw_gpio_pin_construct(base, id, en, ctx))
+               return false;
+
+       pin->funcs = &func;
+
+       pin->pin_reg.DC_GPIO_DATA_MASK.addr = 0;
+       pin->pin_reg.DC_GPIO_DATA_MASK.mask = 0;
+       pin->pin_reg.DC_GPIO_DATA_A.addr = 0;
+       pin->pin_reg.DC_GPIO_DATA_A.mask = 0;
+       pin->pin_reg.DC_GPIO_DATA_EN.addr = 0;
+       pin->pin_reg.DC_GPIO_DATA_EN.mask = 0;
+       pin->pin_reg.DC_GPIO_DATA_Y.addr = 0;
+       pin->pin_reg.DC_GPIO_DATA_Y.mask = 0;
+       pin->mux_reg.GPIO_MUX_CONTROL.addr = 0;
+       pin->mux_reg.GPIO_MUX_CONTROL.mask = 0;
+       pin->mux_reg.GPIO_MUX_STEREO_SEL.addr = 0;
+       pin->mux_reg.GPIO_MUX_STEREO_SEL.mask = 0;
+
+       pin->store.mask = 0;
+       pin->store.a = 0;
+       pin->store.en = 0;
+       pin->store.mux = 0;
+
+       pin->mux_supported = false;
+
+       return true;
+}
+
+void dal_hw_gpio_destruct(
+       struct hw_gpio *pin)
+{
+       dal_hw_gpio_pin_destruct(&pin->base);
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.h
new file mode 100644
index 000000000000..44eb86e1cc32
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_GPIO_H__
+#define __DAL_HW_GPIO_H__
+
+struct addr_mask {
+       uint32_t addr;
+       uint32_t mask;
+};
+
+enum gpio_result dal_hw_gpio_get_reg_value(
+       struct dc_context *ctx,
+       const struct addr_mask *reg,
+       uint32_t *value);
+
+enum gpio_result dal_hw_gpio_set_reg_value(
+       struct dc_context *ctx,
+       const struct addr_mask *reg,
+       uint32_t value);
+
+uint32_t dal_hw_gpio_get_shift_from_mask(
+       uint32_t mask);
+
+struct hw_gpio;
+
+struct hw_gpio_funcs {
+       enum gpio_result (*config_mode)(
+               struct hw_gpio *pin,
+               enum gpio_mode mode);
+};
+
+/* Register indices are represented by member variables
+ * and are to be filled in by constructors of derived classes.
+ * These members permit the use of common code
+ * for programming registers, where the sequence is the same
+ * but register sets are different.
+ * Some GPIOs have HW mux which allows to choose
+ * what is the source of the signal in HW mode */
+
+struct hw_gpio_pin_reg {
+       struct addr_mask DC_GPIO_DATA_MASK;
+       struct addr_mask DC_GPIO_DATA_A;
+       struct addr_mask DC_GPIO_DATA_EN;
+       struct addr_mask DC_GPIO_DATA_Y;
+};
+
+struct hw_gpio_mux_reg {
+       struct addr_mask GPIO_MUX_CONTROL;
+       struct addr_mask GPIO_MUX_STEREO_SEL;
+};
+
+struct hw_gpio {
+       struct hw_gpio_pin base;
+       const struct hw_gpio_funcs *funcs;
+       struct hw_gpio_pin_reg pin_reg;
+       struct hw_gpio_mux_reg mux_reg;
+
+       /* variables to save register value */
+       struct {
+               uint32_t mask;
+               uint32_t a;
+               uint32_t en;
+               uint32_t mux;
+       } store;
+
+       /* GPIO MUX support */
+       bool mux_supported;
+};
+
+#define HW_GPIO_FROM_BASE(hw_gpio_pin) \
+       container_of((hw_gpio_pin), struct hw_gpio, base)
+
+bool dal_hw_gpio_construct(
+       struct hw_gpio *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx);
+
+bool dal_hw_gpio_open(
+       struct hw_gpio_pin *pin,
+       enum gpio_mode mode,
+       void *options);
+
+enum gpio_result dal_hw_gpio_get_value(
+       const struct hw_gpio_pin *pin,
+       uint32_t *value);
+
+enum gpio_result dal_hw_gpio_config_mode(
+       struct hw_gpio *pin,
+       enum gpio_mode mode);
+
+void dal_hw_gpio_destruct(
+       struct hw_gpio *pin);
+
+enum gpio_result dal_hw_gpio_set_value(
+       const struct hw_gpio_pin *ptr,
+       uint32_t value);
+
+enum gpio_result dal_hw_gpio_change_mode(
+       struct hw_gpio_pin *ptr,
+       enum gpio_mode mode);
+
+void dal_hw_gpio_close(
+       struct hw_gpio_pin *ptr);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.c
new file mode 100644
index 000000000000..2392f2ce353b
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+#include "include/gpio_types.h"
+#include "hw_gpio_pin.h"
+#include "hw_gpio.h"
+
+/*
+ * Header of this unit
+ */
+
+#include "hw_gpio_pad.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+/*
+ * This unit
+ */
+
+#define FROM_HW_GPIO(ptr) \
+       container_of((ptr), struct hw_gpio_pad, base)
+
+#define FROM_HW_GPIO_PIN(ptr) \
+       FROM_HW_GPIO(container_of((ptr), struct hw_gpio, base))
+
+enum gpio_result dal_hw_gpio_pad_get_value(
+       const struct hw_gpio_pin *ptr,
+       uint32_t *value)
+{
+       const struct hw_gpio_pad *pin = FROM_HW_GPIO_PIN(ptr);
+
+       if (ptr->mode == GPIO_MODE_INTERRUPT)
+               /* in Interrupt mode, ask for interrupt status bit */
+               return dal_hw_gpio_get_reg_value(
+                       ptr->ctx,
+                       &pin->gpiopad_int_status,
+                       value);
+       else
+               /* for any mode other than Interrupt,
+                * gpio_pad operates as normal GPIO */
+               return dal_hw_gpio_get_value(ptr, value);
+}
+
+bool dal_hw_gpio_pad_construct(
+       struct hw_gpio_pad *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx)
+{
+       if (!dal_hw_gpio_construct(&pin->base, id, en, ctx))
+               return false;
+
+       pin->gpiopad_int_status.addr = 0;
+       pin->gpiopad_int_status.mask = 0;
+
+       return true;
+}
+
+void dal_hw_gpio_pad_destruct(
+       struct hw_gpio_pad *pin)
+{
+       dal_hw_gpio_destruct(&pin->base);
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.h
new file mode 100644
index 000000000000..34b470a11464
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pad.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_GPIO_PAD_H__
+#define __DAL_HW_GPIO_PAD_H__
+
+struct hw_gpio_pad {
+       struct hw_gpio base;
+       struct addr_mask gpiopad_int_status;
+};
+
+bool dal_hw_gpio_pad_construct(
+       struct hw_gpio_pad *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx);
+
+void dal_hw_gpio_pad_destruct(
+       struct hw_gpio_pad *pin);
+
+enum gpio_result dal_hw_gpio_pad_get_value(
+       const struct hw_gpio_pin *ptr,
+       uint32_t *value);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.c
new file mode 100644
index 000000000000..411ad89645e0
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+#include "include/gpio_types.h"
+
+/*
+ * Header of this unit
+ */
+
+#include "hw_gpio_pin.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+/*
+ * This unit
+ */
+enum gpio_result dal_hw_gpio_pin_set_config(
+       struct hw_gpio_pin *pin,
+       const struct gpio_config_data *config_data)
+{
+       /* Attention!
+        * You must override this method in derived class */
+
+       return GPIO_RESULT_NON_SPECIFIC_ERROR;
+}
+
+enum gpio_result dal_hw_gpio_pin_change_mode(
+       struct hw_gpio_pin *pin,
+       enum gpio_mode mode)
+{
+       /* Attention!
+        * You must override this method in derived class */
+
+       return GPIO_RESULT_NON_SPECIFIC_ERROR;
+}
+
+bool dal_hw_gpio_pin_construct(
+       struct hw_gpio_pin *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx)
+{
+       pin->ctx = ctx;
+       pin->id = id;
+       pin->en = en;
+       pin->mode = GPIO_MODE_UNKNOWN;
+       pin->opened = false;
+
+       return true;
+}
+
+void dal_hw_gpio_pin_destruct(
+       struct hw_gpio_pin *pin)
+{
+       ASSERT(!pin->opened);
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.h
new file mode 100644
index 000000000000..d1f2f2712fe2
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_gpio_pin.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_GPIO_PIN_H__
+#define __DAL_HW_GPIO_PIN_H__
+
+struct hw_gpio_pin;
+
+struct hw_gpio_pin_funcs {
+       void (*destroy)(
+               struct hw_gpio_pin **ptr);
+       bool (*open)(
+               struct hw_gpio_pin *pin,
+               enum gpio_mode mode,
+               void *options);
+       enum gpio_result (*get_value)(
+               const struct hw_gpio_pin *pin,
+               uint32_t *value);
+       enum gpio_result (*set_value)(
+               const struct hw_gpio_pin *pin,
+               uint32_t value);
+       enum gpio_result (*set_config)(
+               struct hw_gpio_pin *pin,
+               const struct gpio_config_data *config_data);
+       enum gpio_result (*change_mode)(
+               struct hw_gpio_pin *pin,
+               enum gpio_mode mode);
+       void (*close)(
+               struct hw_gpio_pin *pin);
+};
+
+struct hw_gpio_pin {
+       const struct hw_gpio_pin_funcs *funcs;
+       enum gpio_id id;
+       uint32_t en;
+       enum gpio_mode mode;
+       bool opened;
+       struct dc_context *ctx;
+};
+
+bool dal_hw_gpio_pin_construct(
+       struct hw_gpio_pin *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx);
+
+void dal_hw_gpio_pin_destruct(
+       struct hw_gpio_pin *pin);
+
+enum gpio_result dal_hw_gpio_pin_change_mode(
+       struct hw_gpio_pin *pin,
+       enum gpio_mode mode);
+
+enum gpio_result dal_hw_gpio_pin_set_config(
+       struct hw_gpio_pin *pin,
+       const struct gpio_config_data *config_data);
+#endif
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.c
new file mode 100644
index 000000000000..f072fd551b4a
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+#include "include/gpio_types.h"
+#include "hw_gpio_pin.h"
+#include "hw_gpio.h"
+
+/*
+ * Header of this unit
+ */
+
+#include "hw_hpd.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+/*
+ * This unit
+ */
+
+static enum gpio_result config_mode(
+       struct hw_gpio *pin,
+       enum gpio_mode mode)
+{
+       if (mode == GPIO_MODE_INTERRUPT) {
+               /* Interrupt mode supported only by HPD (IrqGpio) pins. */
+               pin->base.mode = mode;
+
+               return dal_hw_gpio_set_reg_value(
+                       pin->base.ctx,
+                       &pin->pin_reg.DC_GPIO_DATA_MASK,
+                       0);
+       } else
+               /* For any mode other than Interrupt,
+                * act as normal GPIO. */
+               return dal_hw_gpio_config_mode(pin, mode);
+}
+
+const struct hw_gpio_funcs hw_hpd_func = {
+       .config_mode = config_mode,
+};
+
+bool dal_hw_hpd_construct(
+       struct hw_hpd *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx)
+{
+       if (!dal_hw_gpio_construct(&pin->base, id, en, ctx))
+               return false;
+       pin->base.funcs = &hw_hpd_func;
+       return true;
+}
+
+void dal_hw_hpd_destruct(
+       struct hw_hpd *pin)
+{
+       dal_hw_gpio_destruct(&pin->base);
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.h
new file mode 100644
index 000000000000..3fb82df88802
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_hpd.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_HPD_H__
+#define __DAL_HW_HPD_H__
+
+struct hw_hpd {
+       struct hw_gpio base;
+};
+
+#define HW_HPD_FROM_BASE(hw_gpio) \
+       container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_hpd, base)
+
+bool dal_hw_hpd_construct(
+       struct hw_hpd *pin,
+       enum gpio_id id,
+       uint32_t en,
+       struct dc_context *ctx);
+
+void dal_hw_hpd_destruct(
+       struct hw_hpd *pin);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c
new file mode 100644
index 000000000000..215322e9d7e9
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+#include "include/gpio_types.h"
+
+/*
+ * Header of this unit
+ */
+
+#include "hw_translate.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
+#include "dce110/hw_translate_dce110.h"
+#endif
+
+#include "diagnostics/hw_translate_diag.h"
+
+/*
+ * This unit
+ */
+
+bool dal_hw_translate_init(
+       struct hw_translate *translate,
+       enum dce_version dce_version,
+       enum dce_environment dce_environment)
+{
+       if (IS_FPGA_MAXIMUS_DC(dce_environment)) {
+               dal_hw_translate_diag_fpga_init(translate);
+               return true;
+       }
+
+       switch (dce_version) {
+
+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
+#if defined(CONFIG_DRM_AMD_DAL_DCE10_0)
+       case DCE_VERSION_10_0:
+#endif
+       case DCE_VERSION_11_0:
+               dal_hw_translate_dce110_init(translate);
+               return true;
+#endif
+       default:
+               BREAK_TO_DEBUGGER();
+               return false;
+       }
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.h
new file mode 100644
index 000000000000..3a7d89ca1605
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/hw_translate.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_HW_TRANSLATE_H__
+#define __DAL_HW_TRANSLATE_H__
+
+struct hw_translate_funcs {
+       bool (*offset_to_id)(
+               uint32_t offset,
+               uint32_t mask,
+               enum gpio_id *id,
+               uint32_t *en);
+       bool (*id_to_offset)(
+               enum gpio_id id,
+               uint32_t en,
+               struct gpio_pin_info *info);
+};
+
+struct hw_translate {
+       const struct hw_translate_funcs *funcs;
+};
+
+bool dal_hw_translate_init(
+       struct hw_translate *translate,
+       enum dce_version dce_version,
+       enum dce_environment dce_environment);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/irq.c 
b/drivers/gpu/drm/amd/dal/dc/gpio/irq.c
new file mode 100644
index 000000000000..debc2ea48ca1
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/irq.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "dm_services.h"
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+#include "include/gpio_interface.h"
+#include "include/irq_interface.h"
+#include "include/gpio_service_interface.h"
+#include "hw_gpio_pin.h"
+#include "hw_translate.h"
+#include "hw_factory.h"
+#include "gpio_service.h"
+#include "gpio.h"
+
+/*
+ * Header of this unit
+ */
+
+#include "irq.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+/*
+ * This unit
+ */
+
+enum gpio_result dal_irq_open(
+       struct irq *irq)
+{
+       return dal_gpio_open(irq->pin, GPIO_MODE_INTERRUPT);
+}
+
+enum gpio_result dal_irq_get_value(
+       const struct irq *irq,
+       uint32_t *value)
+{
+       return dal_gpio_get_value(irq->pin, value);
+}
+
+enum dc_irq_source dal_irq_get_source(
+       const struct irq *irq)
+{
+       enum gpio_id id = dal_gpio_get_id(irq->pin);
+
+       switch (id) {
+       case GPIO_ID_HPD:
+               return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1 +
+                       dal_gpio_get_enum(irq->pin));
+       case GPIO_ID_GPIO_PAD:
+               return (enum dc_irq_source)(DC_IRQ_SOURCE_GPIOPAD0 +
+                       dal_gpio_get_enum(irq->pin));
+       default:
+               return DC_IRQ_SOURCE_INVALID;
+       }
+}
+
+enum dc_irq_source dal_irq_get_rx_source(
+       const struct irq *irq)
+{
+       enum gpio_id id = dal_gpio_get_id(irq->pin);
+
+       switch (id) {
+       case GPIO_ID_HPD:
+               return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1RX +
+                       dal_gpio_get_enum(irq->pin));
+       default:
+               return DC_IRQ_SOURCE_INVALID;
+       }
+}
+
+enum gpio_result dal_irq_setup_hpd_filter(
+       struct irq *irq,
+       struct gpio_hpd_config *config)
+{
+       struct gpio_config_data config_data;
+
+       if (!config)
+               return GPIO_RESULT_INVALID_DATA;
+
+       config_data.type = GPIO_CONFIG_TYPE_HPD;
+       config_data.config.hpd = *config;
+
+       return dal_gpio_set_config(irq->pin, &config_data);
+}
+
+void dal_irq_close(
+       struct irq *irq)
+{
+       dal_gpio_close(irq->pin);
+}
+
+/*
+ * @brief
+ * Creation and destruction
+ */
+
+struct irq *dal_gpio_create_irq(
+       struct gpio_service *service,
+       enum gpio_id id,
+       uint32_t en)
+{
+       struct irq *irq;
+
+       switch (id) {
+       case GPIO_ID_HPD:
+       case GPIO_ID_GPIO_PAD:
+       break;
+       default:
+               ASSERT_CRITICAL(false);
+               return NULL;
+       }
+
+       irq = dm_alloc(service->ctx, sizeof(struct irq));
+
+       if (!irq) {
+               ASSERT_CRITICAL(false);
+               return NULL;
+       }
+
+       irq->pin = dal_gpio_service_create_gpio_ex(
+               service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
+       irq->ctx = service->ctx;
+
+       if (irq->pin)
+               return irq;
+
+       ASSERT_CRITICAL(false);
+
+       dm_free(service->ctx, irq);
+
+       return NULL;
+}
+
+static void destruct(struct irq *irq)
+{
+       dal_irq_close(irq);
+       dal_gpio_service_destroy_gpio(&irq->pin);
+
+}
+
+void dal_gpio_destroy_irq(
+       struct irq **irq)
+{
+       if (!irq || !*irq) {
+               ASSERT_CRITICAL(false);
+               return;
+       }
+
+       destruct(*irq);
+       dm_free((*irq)->ctx, *irq);
+
+       *irq = NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/dc/gpio/irq.h 
b/drivers/gpu/drm/amd/dal/dc/gpio/irq.h
new file mode 100644
index 000000000000..b69375cd8dc2
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/irq.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_IRQ_H__
+#define __DAL_IRQ_H__
+
+struct irq {
+       struct gpio *pin;
+       struct dc_context *ctx;
+};
+
+struct irq *dal_gpio_create_irq(
+       struct gpio_service *service,
+       enum gpio_id id,
+       uint32_t en);
+
+void dal_gpio_destroy_irq(
+       struct irq **ptr);
+
+#endif
-- 
2.1.4

Reply via email to