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