[PATCH v3 05/26] drm/amd/dal: GPIO (General Purpose IO)

Harry Wentland harry.wentland at amd.com
Mon Feb 29 21:56:29 UTC 2016


v3 changes:
- expose I2C through i2c_adapter and route dal i2c calls through this

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              |  38 +
 .../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, 5105 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..500c3cdd3e56
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/dc/gpio/ddc.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_DDC_H__
+#define __DAL_DDC_H__
+
+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.5.0



More information about the dri-devel mailing list