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
