summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarry Wentland <harry.wentland@amd.com>2015-07-31 15:01:36 -0400
committerAlex Deucher <alexander.deucher@amd.com>2015-09-21 17:45:13 -0400
commitbcd3147acedf04dfcf2f2fa9a2f63d3406dd11e1 (patch)
treea6a4af03bbb86de53e479b012e8b38a39f831006
parent0ce33bcf969c6bf778f6f2046a33ed287553f780 (diff)
amd/dal: GPIO (General Purpose IO)
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. SW Layer /===============================================================\ | Asic | | Capability | | | | | | | | | |---------------------------------------------------------------| | GPIO | | | | | | | \===============================================================/ HW Layer Signed-off-by: Harry Wentland <harry.wentland@amd.com>
-rw-r--r--drivers/gpu/drm/amd/dal/Makefile2
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/Makefile23
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/dce110/hw_ddc_dce110.c883
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/dce110/hw_ddc_dce110.h46
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/dce110/hw_factory_dce110.c84
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/dce110/hw_factory_dce110.h32
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/dce110/hw_hpd_dce110.c367
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/dce110/hw_hpd_dce110.h47
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/dce110/hw_translate_dce110.c440
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/dce110/hw_translate_dce110.h34
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/ddc.c288
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/ddc.h44
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/dvo.c137
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/dvo.h41
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/gpio.c279
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/gpio.h48
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/gpio_service.c469
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/gpio_service.h57
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_ddc.c105
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_ddc.h60
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_dvo.c318
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_dvo.h89
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_factory.c78
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_factory.h74
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_gpio.c408
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_gpio.h129
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_gpio_pad.c93
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_gpio_pad.h47
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_gpio_pin.c86
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_gpio_pin.h79
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_hpd.c88
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_hpd.h45
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_translate.c66
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/hw_translate.h49
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/irq.c180
-rw-r--r--drivers/gpu/drm/amd/dal/gpio/irq.h41
-rw-r--r--drivers/gpu/drm/amd/dal/include/ddc_interface.h74
-rw-r--r--drivers/gpu/drm/amd/dal/include/dvo_interface.h48
-rw-r--r--drivers/gpu/drm/amd/dal/include/gpio_interface.h93
-rw-r--r--drivers/gpu/drm/amd/dal/include/gpio_service_interface.h94
-rw-r--r--drivers/gpu/drm/amd/dal/include/gpio_types.h393
-rw-r--r--drivers/gpu/drm/amd/dal/include/irq_interface.h53
42 files changed, 6110 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/dal/Makefile b/drivers/gpu/drm/amd/dal/Makefile
index bfa934085e3b..09f96a6422ca 100644
--- a/drivers/gpu/drm/amd/dal/Makefile
+++ b/drivers/gpu/drm/amd/dal/Makefile
@@ -7,7 +7,7 @@ AMDDALPATH = $(RELATIVE_AMD_DAL_PATH)
subdir-ccflags-y += -I$(AMDDALPATH)/ -I$(AMDDALPATH)/include -DDAL_CZ_BRINGUP
-DAL_LIBS = amdgpu_dm asic_capability basics
+DAL_LIBS = amdgpu_dm asic_capability basics gpio
AMD_DAL = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DAL_PATH)/,$(DAL_LIBS)))
diff --git a/drivers/gpu/drm/amd/dal/gpio/Makefile b/drivers/gpu/drm/amd/dal/gpio/Makefile
new file mode 100644
index 000000000000..b558a429572c
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/Makefile
@@ -0,0 +1,23 @@
+#
+# Makefile for the 'gpio' sub-component of DAL.
+# It provides the control and status of HW GPIO pins.
+
+GPIO = gpio_service.o gpio.o ddc.o dvo.o irq.o hw_translate.o \
+ hw_factory.o hw_gpio_pin.o hw_gpio.o hw_gpio_pad.o \
+ hw_ddc.o hw_dvo.o hw_hpd.o
+
+AMD_DAL_GPIO = $(addprefix $(AMDDALPATH)/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)/gpio/dce110/,$(GPIO_DCE110))
+
+AMD_DAL_FILES += $(AMD_DAL_GPIO_DCE110)
+endif
diff --git a/drivers/gpu/drm/amd/dal/gpio/dce110/hw_ddc_dce110.c b/drivers/gpu/drm/amd/dal/gpio/dce110/hw_ddc_dce110.c
new file mode 100644
index 000000000000..5e225b6f1224
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/dce110/hw_ddc_dce110.c
@@ -0,0 +1,883 @@
+/*
+ * 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 "dal_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);
+
+ dal_free(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 dal_context *ctx,
+ const uint32_t addr,
+ bool enable_detect,
+ bool detect_mode)
+{
+ uint32_t value;
+
+ value = dal_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);
+
+ dal_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 = dal_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);
+
+ dal_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
+ * dal_delay_in_microseconds(2500); */
+ dal_sleep_in_milliseconds(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;
+
+ dal_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
+ * dal_delay_in_microseconds(2500); */
+ dal_sleep_in_milliseconds(3);
+ }
+
+ if (!scl_pd_dis) {
+ scl_pd_dis = 1;
+
+ dal_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
+ * dal_delay_in_microseconds(2500); */
+ dal_sleep_in_milliseconds(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
+ * dal_delay_in_microseconds(2000); */
+ dal_sleep_in_milliseconds(2);
+
+ /* set the I2C pad mode */
+ /* read the register again,
+ * some bits may have been changed */
+ regval = dal_read_reg(ptr->ctx, addr);
+
+ set_reg_field_value(
+ regval,
+ 0,
+ DC_GPIO_DDC1_MASK,
+ AUX_PAD1_MODE);
+
+ dal_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);
+
+ dal_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 dal_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 dal_context *ctx,
+ enum gpio_id id,
+ uint32_t en)
+{
+ struct hw_ddc_dce110 *pin = dal_alloc(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);
+
+ dal_free(pin);
+
+ return NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/gpio/dce110/hw_ddc_dce110.h b/drivers/gpu/drm/amd/dal/gpio/dce110/hw_ddc_dce110.h
new file mode 100644
index 000000000000..be8a4f16e972
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/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 dal_context *ctx,
+ enum gpio_id id,
+ uint32_t en);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/gpio/dce110/hw_factory_dce110.c b/drivers/gpu/drm/amd/dal/gpio/dce110/hw_factory_dce110.c
new file mode 100644
index 000000000000..85644c5027ae
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/dce110/hw_factory_dce110.c
@@ -0,0 +1,84 @@
+/*
+ * 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 "dal_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_dvo = NULL,
+ .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_DVO1] = 24;
+ factory->number_of_pins[GPIO_ID_DVO12] = 2;
+ factory->number_of_pins[GPIO_ID_DVO24] = 1;
+ 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/gpio/dce110/hw_factory_dce110.h b/drivers/gpu/drm/amd/dal/gpio/dce110/hw_factory_dce110.h
new file mode 100644
index 000000000000..ecf06ed0d587
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/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/gpio/dce110/hw_hpd_dce110.c b/drivers/gpu/drm/amd/dal/gpio/dce110/hw_hpd_dce110.c
new file mode 100644
index 000000000000..7bf6ebf80ec8
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/dce110/hw_hpd_dce110.c
@@ -0,0 +1,367 @@
+/*
+ * 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 "dal_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);
+
+ dal_free(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 = dal_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 = dal_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);
+
+ dal_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 dal_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 dal_context *ctx,
+ enum gpio_id id,
+ uint32_t en)
+{
+ struct hw_hpd_dce110 *pin = dal_alloc(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);
+
+ dal_free(pin);
+
+ return NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/gpio/dce110/hw_hpd_dce110.h b/drivers/gpu/drm/amd/dal/gpio/dce110/hw_hpd_dce110.h
new file mode 100644
index 000000000000..0f8b4fd2a55a
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/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 dal_context *ctx,
+ enum gpio_id id,
+ uint32_t en);
+
+#endif /*__DAL_HW_HPD_DCE110_H__*/
diff --git a/drivers/gpu/drm/amd/dal/gpio/dce110/hw_translate_dce110.c b/drivers/gpu/drm/amd/dal/gpio/dce110/hw_translate_dce110.c
new file mode 100644
index 000000000000..05ac0b28e7ae
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/dce110/hw_translate_dce110.c
@@ -0,0 +1,440 @@
+/*
+ * 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 "dal_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 "../hw_dvo.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) {
+ /* DVO */
+ case mmDC_GPIO_DVODATA_A:
+ switch (mask) {
+ case BUNDLE_A_MASK:
+ *id = GPIO_ID_DVO12;
+ *en = GPIO_DVO12_A;
+ return true;
+ case BUNDLE_B_MASK:
+ *id = GPIO_ID_DVO12;
+ *en = GPIO_DVO12_B;
+ return true;
+ case DC_GPIO_DVODATA_A__DC_GPIO_DVODATA_A_MASK:
+ *id = GPIO_ID_DVO24;
+ *en = 0;
+ return true;
+ default:
+ ASSERT_CRITICAL(false);
+ return false;
+ }
+ break;
+ /* 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_DVO12:
+ info->offset = mmDC_GPIO_DVODATA_A;
+ switch (en) {
+ case GPIO_DVO12_A:
+ info->mask = BUNDLE_A_MASK;
+ break;
+ case GPIO_DVO12_B:
+ info->mask = BUNDLE_B_MASK;
+ break;
+ default:
+ ASSERT_CRITICAL(false);
+ result = false;
+ }
+ break;
+ 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_DVO24:
+ info->offset = mmDC_GPIO_DVODATA_A;
+ info->mask = DC_GPIO_DVODATA_A__DC_GPIO_DVODATA_A_MASK;
+ break;
+ case GPIO_ID_DVO1:
+ 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/gpio/dce110/hw_translate_dce110.h b/drivers/gpu/drm/amd/dal/gpio/dce110/hw_translate_dce110.h
new file mode 100644
index 000000000000..4d16e09853c8
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/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/gpio/ddc.c b/drivers/gpu/drm/amd/dal/gpio/ddc.c
new file mode 100644
index 000000000000..d1ef63f8c8ba
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/ddc.c
@@ -0,0 +1,288 @@
+/*
+ * 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 "dal_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 = dal_alloc(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;
+
+ return ddc;
+
+failure_2:
+ dal_gpio_service_destroy_gpio(&ddc->pin_data);
+
+failure_1:
+ dal_free(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);
+ dal_free(*ddc);
+
+ *ddc = NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/gpio/ddc.h b/drivers/gpu/drm/amd/dal/gpio/ddc.h
new file mode 100644
index 000000000000..06f5f760514e
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/ddc.h
@@ -0,0 +1,44 @@
+/*
+ * 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 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/gpio/dvo.c b/drivers/gpu/drm/amd/dal/gpio/dvo.c
new file mode 100644
index 000000000000..903bf6b45479
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/dvo.c
@@ -0,0 +1,137 @@
+/*
+ * 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 "dal_services.h"
+
+/*
+ * Pre-requisites: headers required by header of this unit
+ */
+
+#include "include/gpio_interface.h"
+#include "include/dvo_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 "dvo.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+/*
+ * This unit
+ */
+
+enum gpio_result dal_dvo_open(
+ struct dvo *dvo,
+ enum gpio_mode mode)
+{
+ return dal_gpio_open(dvo->pin, mode);
+}
+
+enum gpio_result dal_dvo_get_value(
+ const struct dvo *dvo,
+ uint32_t *value)
+{
+ return dal_gpio_get_value(dvo->pin, value);
+}
+
+enum gpio_result dal_dvo_set_value(
+ const struct dvo *dvo,
+ uint32_t value)
+{
+ return dal_gpio_set_value(dvo->pin, value);
+}
+
+void dal_dvo_close(
+ struct dvo *dvo)
+{
+ dal_gpio_close(dvo->pin);
+}
+
+/*
+ * @brief
+ * Creation and destruction
+ */
+
+struct dvo *dal_dvo_create(
+ struct gpio_service *service,
+ enum gpio_id id,
+ uint32_t en)
+{
+ struct dvo *dvo;
+
+ switch (id) {
+ case GPIO_ID_DVO12:
+ if ((en < GPIO_DVO12_MIN) || (en > GPIO_DVO12_MAX)) {
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+ break;
+ case GPIO_ID_DVO24:
+ if ((en < GPIO_DVO24_MIN) || (en > GPIO_DVO24_MAX)) {
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+ break;
+ default:
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+
+ dvo = dal_alloc(sizeof(struct dvo));
+
+ if (!dvo) {
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+
+ dvo->pin = NULL;
+
+ return dvo;
+}
+
+void dal_dvo_destroy(
+ struct dvo **dvo)
+{
+ if (!dvo || !*dvo) {
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+
+ dal_dvo_close(*dvo);
+
+ dal_free(*dvo);
+
+ *dvo = NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/gpio/dvo.h b/drivers/gpu/drm/amd/dal/gpio/dvo.h
new file mode 100644
index 000000000000..2895f2b0f892
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/dvo.h
@@ -0,0 +1,41 @@
+/*
+ * 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_DVO_H__
+#define __DAL_DVO_H__
+
+struct dvo {
+ struct gpio *pin;
+};
+
+struct dvo *dal_dvo_create(
+ struct gpio_service *service,
+ enum gpio_id id,
+ uint32_t en);
+
+void dal_dvo_destroy(
+ struct dvo **dvo);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/gpio/gpio.c b/drivers/gpu/drm/amd/dal/gpio/gpio.c
new file mode 100644
index 000000000000..6adb7084635f
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/gpio.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 "dal_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 = dal_alloc(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);
+
+ dal_free(*gpio);
+
+ *gpio = NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/gpio/gpio.h b/drivers/gpu/drm/amd/dal/gpio/gpio.h
new file mode 100644
index 000000000000..7fcbb6972895
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/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/gpio/gpio_service.c b/drivers/gpu/drm/amd/dal/gpio/gpio_service.c
new file mode 100644
index 000000000000..c95a5f610cf3
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/gpio_service.c
@@ -0,0 +1,469 @@
+/*
+ * 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 "dal_services.h"
+#include "include/gpio_interface.h"
+#include "include/ddc_interface.h"
+#include "include/dvo_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 "dvo.h"
+#include "ddc.h"
+#include "irq.h"
+
+/*
+ * This unit
+ */
+
+/*
+ * @brief
+ * Public API.
+ */
+
+struct gpio_service *dal_gpio_service_create(
+ enum dce_version dce_version,
+ struct dal_context *dal_context)
+{
+ struct gpio_service *service;
+
+ uint32_t index_of_id;
+
+ service = dal_alloc(sizeof(struct gpio_service));
+
+ if (!service) {
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+
+ if (!dal_hw_translate_init(&service->translate, dce_version)) {
+ BREAK_TO_DEBUGGER();
+ goto failure_1;
+ }
+
+ if (!dal_hw_factory_init(&service->factory, dce_version)) {
+ 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->dal_context = dal_context;
+
+ 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 = dal_alloc(
+ 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)
+ dal_free(slot);
+ };
+
+failure_1:
+ dal_free(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 dvo *dal_gpio_service_create_dvo(
+ 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)) {
+ BREAK_TO_DEBUGGER();
+ return NULL;
+ }
+
+ return dal_dvo_create(service, id, en);
+}
+
+struct dvo *dal_gpio_service_create_dvo_ex(
+ struct gpio_service *service,
+ enum gpio_id id,
+ uint32_t en)
+{
+ return dal_dvo_create(service, id, en);
+}
+
+void dal_gpio_service_destroy_dvo(
+ struct dvo **dvo)
+{
+ dal_dvo_destroy(dvo);
+}
+
+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)
+ dal_free(slot);
+
+ ++index_of_id;
+ } while (index_of_id < GPIO_ID_COUNT);
+ }
+
+ dal_free(*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 bool is_some_pin_busy(
+ const struct gpio_service *service,
+ enum gpio_id id)
+{
+ const uint32_t bits_per_uint = sizeof(uint32_t) << 3;
+
+ uint32_t index_of_uint = 0;
+
+ uint32_t number_of_uints =
+ service->factory.number_of_pins[id];
+
+ number_of_uints = (number_of_uints + bits_per_uint - 1) / bits_per_uint;
+
+ while (index_of_uint < number_of_uints) {
+ if (service->busyness[id][index_of_uint])
+ return true;
+
+ ++index_of_uint;
+ };
+
+ return false;
+}
+
+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_DVO1:
+ /* [anaumov] not implemented, commented with "to do" */
+ ASSERT_CRITICAL(false);
+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
+ case GPIO_ID_DVO12:
+ if (!service->busyness[GPIO_ID_DVO24]) {
+ ASSERT_CRITICAL(false);
+ return GPIO_RESULT_OPEN_FAILED;
+ }
+
+ if (is_some_pin_busy(service, GPIO_ID_DVO24)) {
+ ASSERT_CRITICAL(false);
+ return GPIO_RESULT_DEVICE_BUSY;
+ }
+
+ pin = service->factory.funcs->create_dvo(
+ service->dal_context, id, en);
+ break;
+ case GPIO_ID_DVO24:
+ if (!service->busyness[GPIO_ID_DVO12]) {
+ ASSERT_CRITICAL(false);
+ return GPIO_RESULT_OPEN_FAILED;
+ }
+
+ if (is_some_pin_busy(service, GPIO_ID_DVO12)) {
+ ASSERT_CRITICAL(false);
+ return GPIO_RESULT_DEVICE_BUSY;
+ }
+
+ pin = service->factory.funcs->create_dvo(
+ service->dal_context, id, en);
+ break;
+ case GPIO_ID_DDC_DATA:
+ pin = service->factory.funcs->create_ddc_data(
+ service->dal_context, id, en);
+ break;
+ case GPIO_ID_DDC_CLOCK:
+ pin = service->factory.funcs->create_ddc_clock(
+ service->dal_context, id, en);
+ break;
+ case GPIO_ID_GENERIC:
+ pin = service->factory.funcs->create_generic(
+ service->dal_context, id, en);
+ break;
+ case GPIO_ID_HPD:
+ pin = service->factory.funcs->create_hpd(
+ service->dal_context, id, en);
+ break;
+ case GPIO_ID_GPIO_PAD:
+ pin = service->factory.funcs->create_gpio_pad(
+ service->dal_context, id, en);
+ break;
+ case GPIO_ID_SYNC:
+ pin = service->factory.funcs->create_sync(
+ service->dal_context, id, en);
+ break;
+ case GPIO_ID_GSL:
+ pin = service->factory.funcs->create_gsl(
+ service->dal_context, 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/gpio/gpio_service.h b/drivers/gpu/drm/amd/dal/gpio/gpio_service.h
new file mode 100644
index 000000000000..d1ce11927ea9
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/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 dal_context *dal_context;
+ 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/gpio/hw_ddc.c b/drivers/gpu/drm/amd/dal/gpio/hw_ddc.c
new file mode 100644
index 000000000000..20db09c14f95
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/hw_ddc.c
@@ -0,0 +1,105 @@
+/*
+ * 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 "dal_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 dal_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/gpio/hw_ddc.h b/drivers/gpu/drm/amd/dal/gpio/hw_ddc.h
new file mode 100644
index 000000000000..8a04294b9a8a
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/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 dal_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/gpio/hw_dvo.c b/drivers/gpu/drm/amd/dal/gpio/hw_dvo.c
new file mode 100644
index 000000000000..3968abff5968
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/hw_dvo.c
@@ -0,0 +1,318 @@
+/*
+ * 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 "dal_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_dvo.h"
+
+/*
+ * Post-requisites: headers required by this unit
+ */
+
+/*
+ * This unit
+ */
+
+#define FROM_HW_GPIO_PIN(ptr) \
+ container_of((ptr), struct hw_dvo, base)
+
+static void store_dvo_registers(
+ struct hw_dvo *pin)
+{
+ pin->store.dvo_mask = dal_read_reg(
+ pin->base.ctx, pin->addr.DC_GPIO_DVODATA_MASK);
+ pin->store.dvo_en = dal_read_reg(
+ pin->base.ctx, pin->addr.DC_GPIO_DVODATA_EN);
+ pin->store.dvo_data_a = dal_read_reg(
+ pin->base.ctx, pin->addr.DC_GPIO_DVODATA_A);
+}
+
+static void restore_dvo_registers(
+ struct hw_dvo *pin)
+{
+ {
+ const uint32_t addr = pin->addr.DC_GPIO_DVODATA_MASK;
+
+ uint32_t data = dal_read_reg(pin->base.ctx, addr);
+
+ data &= ~pin->dvo_mask;
+ data |= pin->store.dvo_mask & pin->dvo_mask;
+
+ dal_write_reg(pin->base.ctx, addr, data);
+ }
+
+ {
+ const uint32_t addr = pin->addr.DC_GPIO_DVODATA_EN;
+
+ uint32_t data = dal_read_reg(pin->base.ctx, addr);
+
+ data &= ~pin->dvo_mask;
+ data |= pin->store.dvo_en & pin->dvo_mask;
+
+ dal_write_reg(pin->base.ctx, addr, data);
+ }
+
+ {
+ const uint32_t addr = pin->addr.DC_GPIO_DVODATA_A;
+
+ uint32_t data = dal_read_reg(pin->base.ctx, addr);
+
+ data &= ~pin->dvo_mask;
+ data |= pin->store.dvo_data_a & pin->dvo_mask;
+
+ dal_write_reg(pin->base.ctx, addr, data);
+ }
+}
+
+static void program_dvo(
+ struct hw_dvo *pin,
+ bool output)
+{
+ /* Turn on Mask bits for the requested channel,
+ * this will enable the channel for software control. */
+ {
+ const uint32_t addr = pin->addr.DC_GPIO_DVODATA_MASK;
+
+ uint32_t mask = dal_read_reg(pin->base.ctx, addr);
+
+ uint32_t data = pin->dvo_mask | mask;
+
+ dal_write_reg(pin->base.ctx, addr, data);
+ }
+
+ /* Turn off/on the Enable bits on the requested channel,
+ * this will set it to Input/Output mode. */
+ {
+ const uint32_t addr = pin->addr.DC_GPIO_DVODATA_EN;
+
+ uint32_t enable = dal_read_reg(pin->base.ctx, addr);
+
+ uint32_t data = output ?
+ (pin->dvo_mask | enable) :
+ (~pin->dvo_mask & enable);
+
+ dal_write_reg(pin->base.ctx, addr, data);
+ }
+}
+
+static void program_dvo_strength(
+ struct hw_dvo *pin)
+{
+ const uint32_t addr = pin->addr.DVO_STRENGTH_CONTROL;
+
+ uint32_t data = dal_read_reg(pin->base.ctx, addr);
+
+ data &= ~pin->dvo_strength_mask;
+ data |= pin->dvo_strength & pin->dvo_strength_mask;
+
+ dal_write_reg(pin->base.ctx, addr, data);
+}
+
+static void disable_on_chip_terminators(
+ struct hw_dvo *pin)
+{
+ const uint32_t addr = pin->addr.D1CRTC_MVP_CONTROL1;
+
+ uint32_t data = dal_read_reg(pin->base.ctx, addr);
+
+ pin->store.mvp_terminator_state = (data & pin->mvp_termination_mask);
+
+ data &= ~pin->mvp_termination_mask;
+
+ dal_write_reg(pin->base.ctx, addr, data);
+}
+
+static void restore_on_chip_terminators(
+ struct hw_dvo *pin)
+{
+ const uint32_t addr = pin->addr.D1CRTC_MVP_CONTROL1;
+
+ uint32_t data = dal_read_reg(pin->base.ctx, addr);
+
+ data &= ~pin->mvp_termination_mask;
+
+ if (pin->store.mvp_terminator_state)
+ data |= pin->mvp_termination_mask;
+
+ dal_write_reg(pin->base.ctx, addr, data);
+}
+
+bool dal_hw_dvo_open(
+ struct hw_gpio_pin *ptr,
+ enum gpio_mode mode,
+ void *options)
+{
+ struct hw_dvo *pin = FROM_HW_GPIO_PIN(ptr);
+
+ store_dvo_registers(pin);
+
+ ptr->mode = mode;
+
+ switch (mode) {
+ case GPIO_MODE_INPUT:
+ program_dvo_strength(pin);
+ disable_on_chip_terminators(pin);
+ program_dvo(pin, false);
+
+ ptr->opened = true;
+ break;
+ case GPIO_MODE_OUTPUT:
+ program_dvo_strength(pin);
+ disable_on_chip_terminators(pin);
+ program_dvo(pin, true);
+
+ ptr->opened = true;
+ break;
+ default:
+ /* unsupported mode */
+ BREAK_TO_DEBUGGER();
+
+ ptr->opened = false;
+ }
+
+ return ptr->opened;
+}
+
+enum gpio_result dal_hw_dvo_get_value(
+ const struct hw_gpio_pin *ptr,
+ uint32_t *value)
+{
+ const struct hw_dvo *pin = FROM_HW_GPIO_PIN(ptr);
+
+ if (ptr->mode != GPIO_MODE_INPUT)
+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
+
+ *value = dal_read_reg(ptr->ctx, pin->addr.DC_GPIO_DVODATA_Y);
+
+ *value &= pin->dvo_mask;
+ *value >>= pin->dvo_shift;
+
+ return GPIO_RESULT_OK;
+}
+
+enum gpio_result dal_hw_dvo_set_value(
+ const struct hw_gpio_pin *ptr,
+ uint32_t value)
+{
+ const struct hw_dvo *pin = FROM_HW_GPIO_PIN(ptr);
+
+ uint32_t masked_value;
+
+ if (ptr->mode != GPIO_MODE_OUTPUT) {
+ BREAK_TO_DEBUGGER();
+ return GPIO_RESULT_NON_SPECIFIC_ERROR;
+ }
+
+ /* Ensure there is no overflow of the value written.
+ * Value cannot be more than 12 bits for a 12-bit channel. */
+
+ masked_value = value << pin->dvo_shift;
+
+ if (masked_value != (masked_value & pin->dvo_mask)) {
+ BREAK_TO_DEBUGGER();
+ return GPIO_RESULT_INVALID_DATA;
+ }
+
+ masked_value &= pin->dvo_mask;
+
+ /* read the DataA register
+ * mask off the Bundle that we want to write to
+ * or the data into the register */
+ {
+ const uint32_t addr = pin->addr.DC_GPIO_DVODATA_A;
+
+ uint32_t data = dal_read_reg(ptr->ctx, addr);
+
+ data &= ~pin->dvo_mask;
+ data |= masked_value;
+
+ dal_write_reg(ptr->ctx, addr, data);
+ }
+
+ return GPIO_RESULT_OK;
+}
+
+void dal_hw_dvo_close(
+ struct hw_gpio_pin *ptr)
+{
+ struct hw_dvo *pin = FROM_HW_GPIO_PIN(ptr);
+
+ restore_dvo_registers(pin);
+ restore_on_chip_terminators(pin);
+
+ ptr->mode = GPIO_MODE_UNKNOWN;
+
+ ptr->opened = false;
+}
+
+bool dal_hw_dvo_construct(
+ struct hw_dvo *pin,
+ enum gpio_id id,
+ uint32_t en,
+ struct dal_context *ctx)
+{
+ struct hw_gpio_pin *base = &pin->base;
+
+ if (!dal_hw_gpio_pin_construct(base, id, en, ctx))
+ return false;
+
+ pin->addr.DC_GPIO_DVODATA_MASK = 0;
+ pin->addr.DC_GPIO_DVODATA_EN = 0;
+ pin->addr.DC_GPIO_DVODATA_A = 0;
+ pin->addr.DC_GPIO_DVODATA_Y = 0;
+ pin->addr.DVO_STRENGTH_CONTROL = 0;
+ pin->addr.D1CRTC_MVP_CONTROL1 = 0;
+
+ pin->dvo_mask = 0;
+ pin->dvo_shift = 0;
+ pin->dvo_strength_mask = 0;
+ pin->mvp_termination_mask = 0;
+
+ pin->dvo_strength = 0;
+
+ pin->store.dvo_mask = 0;
+ pin->store.dvo_en = 0;
+ pin->store.dvo_data_a = 0;
+ pin->store.mvp_terminator_state = false;
+
+ return true;
+}
+
+void dal_hw_dvo_destruct(
+ struct hw_dvo *pin)
+{
+ dal_hw_gpio_pin_destruct(&pin->base);
+}
diff --git a/drivers/gpu/drm/amd/dal/gpio/hw_dvo.h b/drivers/gpu/drm/amd/dal/gpio/hw_dvo.h
new file mode 100644
index 000000000000..c4987d3fb283
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/hw_dvo.h
@@ -0,0 +1,89 @@
+/*
+ * 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_DVO_H__
+#define __DAL_HW_DVO_H__
+
+#define BUNDLE_A_SHIFT 12L
+#define BUNDLE_B_SHIFT 0L
+
+struct hw_dvo {
+ struct hw_gpio_pin base;
+ /* Register indices are represented by member variables,
+ * are to be filled in by derived classes.
+ * These members permit the use of common code
+ * for programming registers where the sequence is the same
+ * but the register sets are different */
+ struct {
+ uint32_t DC_GPIO_DVODATA_MASK;
+ uint32_t DC_GPIO_DVODATA_EN;
+ uint32_t DC_GPIO_DVODATA_A;
+ uint32_t DC_GPIO_DVODATA_Y;
+ uint32_t DVO_STRENGTH_CONTROL;
+ uint32_t D1CRTC_MVP_CONTROL1;
+ } addr;
+
+ /* Mask and shift differentiates between Bundle A and Bundle B */
+ uint32_t dvo_mask;
+ uint32_t dvo_shift;
+ uint32_t dvo_strength_mask;
+ uint32_t mvp_termination_mask;
+
+ uint32_t dvo_strength;
+
+ struct {
+ uint32_t dvo_mask;
+ uint32_t dvo_en;
+ uint32_t dvo_data_a;
+ bool mvp_terminator_state;
+ } store;
+};
+
+bool dal_hw_dvo_construct(
+ struct hw_dvo *pin,
+ enum gpio_id id,
+ uint32_t en,
+ struct dal_context *ctx);
+
+void dal_hw_dvo_destruct(
+ struct hw_dvo *pin);
+
+bool dal_hw_dvo_open(
+ struct hw_gpio_pin *ptr,
+ enum gpio_mode mode,
+ void *options);
+
+enum gpio_result dal_hw_dvo_get_value(
+ const struct hw_gpio_pin *ptr,
+ uint32_t *value);
+
+enum gpio_result dal_hw_dvo_set_value(
+ const struct hw_gpio_pin *ptr,
+ uint32_t value);
+
+void dal_hw_dvo_close(
+ struct hw_gpio_pin *ptr);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/gpio/hw_factory.c b/drivers/gpu/drm/amd/dal/gpio/hw_factory.c
new file mode 100644
index 000000000000..943f735299a9
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/hw_factory.c
@@ -0,0 +1,78 @@
+/*
+ * 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 "dal_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
+/*
+ * This unit
+ */
+
+bool dal_hw_factory_init(
+ struct hw_factory *factory,
+ enum dce_version dce_version)
+{
+ switch (dce_version) {
+#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 hw_factory **factory)
+{
+ if (!factory || !*factory) {
+ BREAK_TO_DEBUGGER();
+ return;
+ }
+
+ dal_free(*factory);
+
+ *factory = NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/gpio/hw_factory.h b/drivers/gpu/drm/amd/dal/gpio/hw_factory.h
new file mode 100644
index 000000000000..010fa07b3b4d
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/hw_factory.h
@@ -0,0 +1,74 @@
+/*
+ * 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_dvo)(
+ struct dal_context *ctx,
+ enum gpio_id id,
+ uint32_t en);
+ struct hw_gpio_pin *(*create_ddc_data)(
+ struct dal_context *ctx,
+ enum gpio_id id,
+ uint32_t en);
+ struct hw_gpio_pin *(*create_ddc_clock)(
+ struct dal_context *ctx,
+ enum gpio_id id,
+ uint32_t en);
+ struct hw_gpio_pin *(*create_generic)(
+ struct dal_context *ctx,
+ enum gpio_id id,
+ uint32_t en);
+ struct hw_gpio_pin *(*create_hpd)(
+ struct dal_context *ctx,
+ enum gpio_id id,
+ uint32_t en);
+ struct hw_gpio_pin *(*create_gpio_pad)(
+ struct dal_context *ctx,
+ enum gpio_id id,
+ uint32_t en);
+ struct hw_gpio_pin *(*create_sync)(
+ struct dal_context *ctx,
+ enum gpio_id id,
+ uint32_t en);
+ struct hw_gpio_pin *(*create_gsl)(
+ struct dal_context *ctx,
+ enum gpio_id id,
+ uint32_t en);
+ } *funcs;
+};
+
+bool dal_hw_factory_init(
+ struct hw_factory *factory,
+ enum dce_version dce_version);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/gpio/hw_gpio.c b/drivers/gpu/drm/amd/dal/gpio/hw_gpio.c
new file mode 100644
index 000000000000..af9e439c3dd0
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/hw_gpio.c
@@ -0,0 +1,408 @@
+/*
+ * 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 "dal_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 dal_context *ctx,
+ const struct addr_mask *reg,
+ uint32_t *value)
+{
+ *value = dal_read_reg(ctx, reg->addr);
+
+ *value &= reg->mask;
+
+ return GPIO_RESULT_OK;
+}
+
+enum gpio_result dal_hw_gpio_set_reg_value(
+ struct dal_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 = dal_read_reg(ctx, reg->addr);
+
+ prev_value &= ~reg->mask;
+ prev_value |= (value & reg->mask);
+
+ dal_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 dal_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/gpio/hw_gpio.h b/drivers/gpu/drm/amd/dal/gpio/hw_gpio.h
new file mode 100644
index 000000000000..483e00a7fed6
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/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 dal_context *ctx,
+ const struct addr_mask *reg,
+ uint32_t *value);
+
+enum gpio_result dal_hw_gpio_set_reg_value(
+ struct dal_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 dal_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/gpio/hw_gpio_pad.c b/drivers/gpu/drm/amd/dal/gpio/hw_gpio_pad.c
new file mode 100644
index 000000000000..1b0eeaf95b29
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/hw_gpio_pad.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 "dal_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 dal_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/gpio/hw_gpio_pad.h b/drivers/gpu/drm/amd/dal/gpio/hw_gpio_pad.h
new file mode 100644
index 000000000000..5f28a33537ca
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/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 dal_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/gpio/hw_gpio_pin.c b/drivers/gpu/drm/amd/dal/gpio/hw_gpio_pin.c
new file mode 100644
index 000000000000..9e921f174dea
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/hw_gpio_pin.c
@@ -0,0 +1,86 @@
+/*
+ * 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 "dal_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 dal_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/gpio/hw_gpio_pin.h b/drivers/gpu/drm/amd/dal/gpio/hw_gpio_pin.h
new file mode 100644
index 000000000000..ee65657612a4
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/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 dal_context *ctx;
+};
+
+bool dal_hw_gpio_pin_construct(
+ struct hw_gpio_pin *pin,
+ enum gpio_id id,
+ uint32_t en,
+ struct dal_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/gpio/hw_hpd.c b/drivers/gpu/drm/amd/dal/gpio/hw_hpd.c
new file mode 100644
index 000000000000..5a875ea88a38
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/hw_hpd.c
@@ -0,0 +1,88 @@
+/*
+ * 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 "dal_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 dal_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/gpio/hw_hpd.h b/drivers/gpu/drm/amd/dal/gpio/hw_hpd.h
new file mode 100644
index 000000000000..65a4e5f41d9c
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/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 dal_context *ctx);
+
+void dal_hw_hpd_destruct(
+ struct hw_hpd *pin);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/gpio/hw_translate.c b/drivers/gpu/drm/amd/dal/gpio/hw_translate.c
new file mode 100644
index 000000000000..a77ac35d0489
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/hw_translate.c
@@ -0,0 +1,66 @@
+/*
+ * 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 "dal_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
+
+/*
+ * This unit
+ */
+
+bool dal_hw_translate_init(
+ struct hw_translate *translate,
+ enum dce_version dce_version)
+{
+ switch (dce_version) {
+#if defined(CONFIG_DRM_AMD_DAL_DCE11_0)
+ 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/gpio/hw_translate.h b/drivers/gpu/drm/amd/dal/gpio/hw_translate.h
new file mode 100644
index 000000000000..d5740ac1ed10
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/hw_translate.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012-15 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef __DAL_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);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/gpio/irq.c b/drivers/gpu/drm/amd/dal/gpio/irq.c
new file mode 100644
index 000000000000..e8522df3f1cc
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/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 "dal_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 dal_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 dal_irq_source)(DAL_IRQ_SOURCE_HPD1 +
+ dal_gpio_get_enum(irq->pin));
+ case GPIO_ID_GPIO_PAD:
+ return (enum dal_irq_source)(DAL_IRQ_SOURCE_GPIOPAD0 +
+ dal_gpio_get_enum(irq->pin));
+ default:
+ return DAL_IRQ_SOURCE_INVALID;
+ }
+}
+
+enum dal_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 dal_irq_source)(DAL_IRQ_SOURCE_HPD1RX +
+ dal_gpio_get_enum(irq->pin));
+ default:
+ return DAL_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 = dal_alloc(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);
+
+ if (irq->pin)
+ return irq;
+
+ ASSERT_CRITICAL(false);
+
+ dal_free(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);
+ dal_free(*irq);
+
+ *irq = NULL;
+}
diff --git a/drivers/gpu/drm/amd/dal/gpio/irq.h b/drivers/gpu/drm/amd/dal/gpio/irq.h
new file mode 100644
index 000000000000..2fb1cce00869
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/gpio/irq.h
@@ -0,0 +1,41 @@
+/*
+ * 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 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
diff --git a/drivers/gpu/drm/amd/dal/include/ddc_interface.h b/drivers/gpu/drm/amd/dal/include/ddc_interface.h
new file mode 100644
index 000000000000..22fd31f6de7f
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/include/ddc_interface.h
@@ -0,0 +1,74 @@
+/*
+ * 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_INTERFACE_H__
+#define __DAL_DDC_INTERFACE_H__
+
+#include "gpio_types.h"
+
+struct ddc;
+
+enum gpio_result dal_ddc_open(
+ struct ddc *ddc,
+ enum gpio_mode mode,
+ enum gpio_ddc_config_type config_type);
+
+enum gpio_result dal_ddc_get_clock(
+ const struct ddc *ddc,
+ uint32_t *value);
+
+enum gpio_result dal_ddc_set_clock(
+ const struct ddc *ddc,
+ uint32_t value);
+
+enum gpio_result dal_ddc_get_data(
+ const struct ddc *ddc,
+ uint32_t *value);
+
+enum gpio_result dal_ddc_set_data(
+ const struct ddc *ddc,
+ uint32_t value);
+
+enum gpio_result dal_ddc_change_mode(
+ struct ddc *ddc,
+ enum gpio_mode mode);
+
+bool dal_ddc_is_hw_supported(
+ const struct ddc *ddc);
+
+enum gpio_ddc_line dal_ddc_get_line(
+ const struct ddc *ddc);
+
+bool dal_ddc_check_line_aborted(
+ const struct ddc *ddc);
+
+enum gpio_result dal_ddc_set_config(
+ struct ddc *ddc,
+ enum gpio_ddc_config_type config_type);
+
+void dal_ddc_close(
+ struct ddc *ddc);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/include/dvo_interface.h b/drivers/gpu/drm/amd/dal/include/dvo_interface.h
new file mode 100644
index 000000000000..58d2c6f283df
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/include/dvo_interface.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_DVO_INTERFACE_H__
+#define __DAL_DVO_INTERFACE_H__
+
+#include "gpio_types.h"
+
+struct dvo;
+
+enum gpio_result dal_dvo_open(
+ struct dvo *dvo,
+ enum gpio_mode mode);
+
+enum gpio_result dal_dvo_get_value(
+ const struct dvo *dvo,
+ uint32_t *value);
+
+enum gpio_result dal_dvo_set_value(
+ const struct dvo *dvo,
+ uint32_t value);
+
+void dal_dvo_close(
+ struct dvo *dvo);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/include/gpio_interface.h b/drivers/gpu/drm/amd/dal/include/gpio_interface.h
new file mode 100644
index 000000000000..a084d7923e2f
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/include/gpio_interface.h
@@ -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
+ *
+ */
+
+#ifndef __DAL_GPIO_INTERFACE_H__
+#define __DAL_GPIO_INTERFACE_H__
+
+#include "gpio_types.h"
+#include "grph_object_defs.h"
+
+struct gpio;
+
+/* Open the handle for future use */
+enum gpio_result dal_gpio_open(
+ struct gpio *gpio,
+ enum gpio_mode mode);
+
+enum gpio_result dal_gpio_open_ex(
+ struct gpio *gpio,
+ enum gpio_mode mode,
+ void *options);
+
+/* Get high or low from the pin */
+enum gpio_result dal_gpio_get_value(
+ const struct gpio *gpio,
+ uint32_t *value);
+
+/* Set pin high or low */
+enum gpio_result dal_gpio_set_value(
+ const struct gpio *gpio,
+ uint32_t value);
+
+/* Get current mode */
+enum gpio_mode dal_gpio_get_mode(
+ const struct gpio *gpio);
+
+/* Change mode of the handle */
+enum gpio_result dal_gpio_change_mode(
+ struct gpio *gpio,
+ enum gpio_mode mode);
+
+/* Get the GPIO id */
+enum gpio_id dal_gpio_get_id(
+ const struct gpio *gpio);
+
+/* Get the GPIO enum */
+uint32_t dal_gpio_get_enum(
+ const struct gpio *gpio);
+
+/* Set the GPIO pin configuration */
+enum gpio_result dal_gpio_set_config(
+ struct gpio *gpio,
+ const struct gpio_config_data *config_data);
+
+/* Obtain GPIO pin info */
+enum gpio_result dal_gpio_get_pin_info(
+ const struct gpio *gpio,
+ struct gpio_pin_info *pin_info);
+
+/* Obtain GPIO sync source */
+enum sync_source dal_gpio_get_sync_source(
+ const struct gpio *gpio);
+
+/* Obtain GPIO pin output state (active low or active high) */
+enum gpio_pin_output_state dal_gpio_get_output_state(
+ const struct gpio *gpio);
+
+/* Close the handle */
+void dal_gpio_close(
+ struct gpio *gpio);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/include/gpio_service_interface.h b/drivers/gpu/drm/amd/dal/include/gpio_service_interface.h
new file mode 100644
index 000000000000..7adb187b45ef
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/include/gpio_service_interface.h
@@ -0,0 +1,94 @@
+/*
+ * 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_INTERFACE_H__
+#define __DAL_GPIO_SERVICE_INTERFACE_H__
+
+#include "gpio_types.h"
+#include "gpio_interface.h"
+#include "dvo_interface.h"
+#include "ddc_interface.h"
+#include "irq_interface.h"
+
+struct gpio_service;
+
+struct gpio_service *dal_gpio_service_create(
+ enum dce_version dce_version,
+ struct dal_context *dal_context);
+
+struct gpio *dal_gpio_service_create_gpio(
+ struct gpio_service *service,
+ uint32_t offset,
+ uint32_t mask,
+ enum gpio_pin_output_state 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);
+
+void dal_gpio_service_destroy_gpio(
+ struct gpio **gpio);
+
+struct ddc *dal_gpio_service_create_ddc(
+ struct gpio_service *service,
+ uint32_t offset,
+ uint32_t mask,
+ struct gpio_ddc_hw_info *info);
+
+void dal_gpio_service_destroy_ddc(
+ struct ddc **ddc);
+
+struct dvo *dal_gpio_service_create_dvo(
+ struct gpio_service *service,
+ uint32_t offset,
+ uint32_t mask);
+
+struct dvo *dal_gpio_service_create_dvo_ex(
+ struct gpio_service *service,
+ enum gpio_id id,
+ uint32_t en);
+
+void dal_gpio_service_destroy_dvo(
+ struct dvo **ptr);
+
+struct irq *dal_gpio_service_create_irq(
+ struct gpio_service *service,
+ uint32_t offset,
+ uint32_t mask);
+
+struct irq *dal_gpio_service_create_irq_ex(
+ struct gpio_service *service,
+ enum gpio_id id,
+ uint32_t en);
+
+void dal_gpio_service_destroy_irq(
+ struct irq **ptr);
+
+void dal_gpio_service_destroy(
+ struct gpio_service **ptr);
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/include/gpio_types.h b/drivers/gpu/drm/amd/dal/include/gpio_types.h
new file mode 100644
index 000000000000..d616d62c78e0
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/include/gpio_types.h
@@ -0,0 +1,393 @@
+/*
+ * 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_TYPES_H__
+#define __DAL_GPIO_TYPES_H__
+
+#define BUNDLE_A_MASK 0x00FFF000L
+#define BUNDLE_B_MASK 0x00000FFFL
+
+/*
+ * gpio_result
+ *
+ * @brief
+ * The possible return codes that the GPIO object can return.
+ * These return codes can be generated
+ * directly by the GPIO object or from the GPIOPin object.
+ */
+enum gpio_result {
+ GPIO_RESULT_OK,
+ GPIO_RESULT_NULL_HANDLE,
+ GPIO_RESULT_INVALID_DATA,
+ GPIO_RESULT_DEVICE_BUSY,
+ GPIO_RESULT_OPEN_FAILED,
+ GPIO_RESULT_ALREADY_OPENED,
+ GPIO_RESULT_NON_SPECIFIC_ERROR
+};
+
+/*
+ * @brief
+ * Used to identify the specific GPIO device
+ *
+ * @notes
+ * These constants are used as indices in a vector.
+ * Thus they should start from zero and be contiguous.
+ */
+enum gpio_id {
+ GPIO_ID_UNKNOWN = (-1),
+ GPIO_ID_DVO1,
+ GPIO_ID_DVO12,
+ GPIO_ID_DVO24,
+ GPIO_ID_DDC_DATA,
+ GPIO_ID_DDC_CLOCK,
+ GPIO_ID_GENERIC,
+ GPIO_ID_HPD,
+ GPIO_ID_GPIO_PAD,
+ GPIO_ID_VIP_PAD,
+ GPIO_ID_SYNC,
+ GPIO_ID_GSL, /* global swap lock */
+ GPIO_ID_COUNT,
+ GPIO_ID_MIN = GPIO_ID_DVO1,
+ GPIO_ID_MAX = GPIO_ID_GSL
+};
+
+#define GPIO_ENUM_UNKNOWN \
+ 32
+
+struct gpio_pin_info {
+ uint32_t offset;
+ uint32_t offset_y;
+ uint32_t offset_en;
+ uint32_t offset_mask;
+
+ uint32_t mask;
+ uint32_t mask_y;
+ uint32_t mask_en;
+ uint32_t mask_mask;
+};
+
+enum gpio_pin_output_state {
+ GPIO_PIN_OUTPUT_STATE_ACTIVE_LOW,
+ GPIO_PIN_OUTPUT_STATE_ACTIVE_HIGH,
+ GPIO_PIN_OUTPUT_STATE_DEFAULT = GPIO_PIN_OUTPUT_STATE_ACTIVE_LOW
+};
+
+enum gpio_dvo1 {
+ GPIO_DVO1_UNKNOWN = (-1),
+ GPIO_DVO1_0,
+ GPIO_DVO1_1,
+ GPIO_DVO1_2,
+ GPIO_DVO1_3,
+ GPIO_DVO1_4,
+ GPIO_DVO1_5,
+ GPIO_DVO1_6,
+ GPIO_DVO1_7,
+ GPIO_DVO1_8,
+ GPIO_DVO1_9,
+ GPIO_DVO1_10,
+ GPIO_DVO1_11,
+ GPIO_DVO1_12,
+ GPIO_DVO1_13,
+ GPIO_DVO1_14,
+ GPIO_DVO1_15,
+ GPIO_DVO1_16,
+ GPIO_DVO1_17,
+ GPIO_DVO1_18,
+ GPIO_DVO1_19,
+ GPIO_DVO1_20,
+ GPIO_DVO1_21,
+ GPIO_DVO1_22,
+ GPIO_DVO1_23,
+ GPIO_DVO1_COUNT,
+ GPIO_DVO1_MIN = GPIO_DVO1_0,
+ GPIO_DVO1_MAX = GPIO_DVO1_23
+};
+
+enum gpio_dvo12 {
+ GPIO_DVO12_UNKNOWN = (-1),
+ GPIO_DVO12_A,
+ GPIO_DVO12_B,
+ GPIO_DVO12_COUNT,
+ GPIO_DVO12_MIN = GPIO_DVO12_A,
+ GPIO_DVO12_MAX = GPIO_DVO12_B
+};
+
+enum gpio_dvo24 {
+ GPIO_DVO24_UNKNOWN = (-1),
+ GPIO_DVO24_A,
+ GPIO_DVO24_COUNT,
+ GPIO_DVO24_MIN = GPIO_DVO24_A,
+ GPIO_DVO24_MAX = GPIO_DVO24_A
+};
+
+enum gpio_generic {
+ GPIO_GENERIC_UNKNOWN = (-1),
+ GPIO_GENERIC_A,
+ GPIO_GENERIC_B,
+ GPIO_GENERIC_C,
+ GPIO_GENERIC_D,
+ GPIO_GENERIC_E,
+ GPIO_GENERIC_F,
+ GPIO_GENERIC_G,
+ GPIO_GENERIC_COUNT,
+ GPIO_GENERIC_MIN = GPIO_GENERIC_A,
+ GPIO_GENERIC_MAX = GPIO_GENERIC_B
+};
+
+enum gpio_hpd {
+ GPIO_HPD_UNKNOWN = (-1),
+ GPIO_HPD_1,
+ GPIO_HPD_2,
+ GPIO_HPD_3,
+ GPIO_HPD_4,
+ GPIO_HPD_5,
+ GPIO_HPD_6,
+ GPIO_HPD_COUNT,
+ GPIO_HPD_MIN = GPIO_HPD_1,
+ GPIO_HPD_MAX = GPIO_HPD_6
+};
+
+enum gpio_gpio_pad {
+ GPIO_GPIO_PAD_UNKNOWN = (-1),
+ GPIO_GPIO_PAD_0,
+ GPIO_GPIO_PAD_1,
+ GPIO_GPIO_PAD_2,
+ GPIO_GPIO_PAD_3,
+ GPIO_GPIO_PAD_4,
+ GPIO_GPIO_PAD_5,
+ GPIO_GPIO_PAD_6,
+ GPIO_GPIO_PAD_7,
+ GPIO_GPIO_PAD_8,
+ GPIO_GPIO_PAD_9,
+ GPIO_GPIO_PAD_10,
+ GPIO_GPIO_PAD_11,
+ GPIO_GPIO_PAD_12,
+ GPIO_GPIO_PAD_13,
+ GPIO_GPIO_PAD_14,
+ GPIO_GPIO_PAD_15,
+ GPIO_GPIO_PAD_16,
+ GPIO_GPIO_PAD_17,
+ GPIO_GPIO_PAD_18,
+ GPIO_GPIO_PAD_19,
+ GPIO_GPIO_PAD_20,
+ GPIO_GPIO_PAD_21,
+ GPIO_GPIO_PAD_22,
+ GPIO_GPIO_PAD_23,
+ GPIO_GPIO_PAD_24,
+ GPIO_GPIO_PAD_25,
+ GPIO_GPIO_PAD_26,
+ GPIO_GPIO_PAD_27,
+ GPIO_GPIO_PAD_28,
+ GPIO_GPIO_PAD_29,
+ GPIO_GPIO_PAD_30,
+ GPIO_GPIO_PAD_COUNT,
+ GPIO_GPIO_PAD_MIN = GPIO_GPIO_PAD_0,
+ GPIO_GPIO_PAD_MAX = GPIO_GPIO_PAD_30
+};
+
+enum gpio_vip_pad {
+ GPIO_VIP_PAD_UNKNOWN = (-1),
+ /* following never used -
+ * GPIO_ID_DDC_CLOCK::GPIO_DDC_LINE_VIP_PAD defined instead */
+ GPIO_VIP_PAD_SCL,
+ /* following never used -
+ * GPIO_ID_DDC_DATA::GPIO_DDC_LINE_VIP_PAD defined instead */
+ GPIO_VIP_PAD_SDA,
+ GPIO_VIP_PAD_VHAD,
+ GPIO_VIP_PAD_VPHCTL,
+ GPIO_VIP_PAD_VIPCLK,
+ GPIO_VIP_PAD_VID,
+ GPIO_VIP_PAD_VPCLK0,
+ GPIO_VIP_PAD_DVALID,
+ GPIO_VIP_PAD_PSYNC,
+ GPIO_VIP_PAD_COUNT,
+ GPIO_VIP_PAD_MIN = GPIO_VIP_PAD_SCL,
+ GPIO_VIP_PAD_MAX = GPIO_VIP_PAD_PSYNC
+};
+
+enum gpio_sync {
+ GPIO_SYNC_UNKNOWN = (-1),
+ GPIO_SYNC_HSYNC_A,
+ GPIO_SYNC_VSYNC_A,
+ GPIO_SYNC_HSYNC_B,
+ GPIO_SYNC_VSYNC_B,
+ GPIO_SYNC_COUNT,
+ GPIO_SYNC_MIN = GPIO_SYNC_HSYNC_A,
+ GPIO_SYNC_MAX = GPIO_SYNC_VSYNC_B
+};
+
+enum gpio_gsl {
+ GPIO_GSL_UNKNOWN = (-1),
+ GPIO_GSL_GENLOCK_CLOCK,
+ GPIO_GSL_GENLOCK_VSYNC,
+ GPIO_GSL_SWAPLOCK_A,
+ GPIO_GSL_SWAPLOCK_B,
+ GPIO_GSL_COUNT,
+ GPIO_GSL_MIN = GPIO_GSL_GENLOCK_CLOCK,
+ GPIO_GSL_MAX = GPIO_GSL_SWAPLOCK_B
+};
+
+/*
+ * @brief
+ * Unique Id for DDC handle.
+ * Values are meaningful (used as indexes to array)
+ */
+enum gpio_ddc_line {
+ GPIO_DDC_LINE_UNKNOWN = (-1),
+ GPIO_DDC_LINE_DDC1,
+ GPIO_DDC_LINE_DDC2,
+ GPIO_DDC_LINE_DDC3,
+ GPIO_DDC_LINE_DDC4,
+ GPIO_DDC_LINE_DDC5,
+ GPIO_DDC_LINE_DDC6,
+ GPIO_DDC_LINE_DDC_VGA,
+ GPIO_DDC_LINE_VIP_PAD,
+ GPIO_DDC_LINE_I2C_PAD = GPIO_DDC_LINE_VIP_PAD,
+ GPIO_DDC_LINE_COUNT,
+ GPIO_DDC_LINE_MIN = GPIO_DDC_LINE_DDC1,
+ GPIO_DDC_LINE_MAX = GPIO_DDC_LINE_I2C_PAD
+};
+
+/*
+ * @brief
+ * Identifies the mode of operation to open a GPIO device.
+ * A GPIO device (pin) can be programmed in only one of these modes at a time.
+ */
+enum gpio_mode {
+ GPIO_MODE_UNKNOWN = (-1),
+ GPIO_MODE_INPUT,
+ GPIO_MODE_OUTPUT,
+ GPIO_MODE_FAST_OUTPUT,
+ GPIO_MODE_HARDWARE,
+ GPIO_MODE_INTERRUPT
+};
+
+/*
+ * @brief
+ * Identifies the source of the signal when GPIO is in HW mode.
+ * get_signal_source() will return GPIO_SYGNAL_SOURCE__UNKNOWN
+ * when one of the following holds:
+ * 1. GPIO is input GPIO
+ * 2. GPIO is not opened in HW mode
+ * 3. GPIO does not have fixed signal source
+ * (like DC_GenericA have mux instead fixed)
+ */
+enum gpio_signal_source {
+ GPIO_SIGNAL_SOURCE_UNKNOWN = (-1),
+ GPIO_SIGNAL_SOURCE_DACA_STEREO_SYNC,
+ GPIO_SIGNAL_SOURCE_PASS_THROUGH_STEREO_SYNC,
+ GPIO_SIGNAL_SOURCE_DACB_STEREO_SYNC,
+ GPIO_SIGNAL_SOURCE_DACA_HSYNC,
+ GPIO_SIGNAL_SOURCE_DACB_HSYNC,
+ GPIO_SIGNAL_SOURCE_DACA_VSYNC,
+ GPIO_SIGNAL_SOURCE_DACB_VSYNC,
+ GPIO_SIGNAL_SOURCE_DVO_STEREO_SYNC
+};
+
+enum gpio_stereo_source {
+ GPIO_STEREO_SOURCE_UNKNOWN = (-1),
+ GPIO_STEREO_SOURCE_D1,
+ GPIO_STEREO_SOURCE_D2,
+ GPIO_STEREO_SOURCE_D3,
+ GPIO_STEREO_SOURCE_D4,
+ GPIO_STEREO_SOURCE_D5,
+ GPIO_STEREO_SOURCE_D6
+};
+
+/*
+ * GPIO config
+ */
+
+enum gpio_config_type {
+ GPIO_CONFIG_TYPE_NONE,
+ GPIO_CONFIG_TYPE_DDC,
+ GPIO_CONFIG_TYPE_HPD,
+ GPIO_CONFIG_TYPE_GENERIC_MUX,
+ GPIO_CONFIG_TYPE_GSL_MUX,
+ GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE
+};
+
+/* DDC configuration */
+
+enum gpio_ddc_config_type {
+ GPIO_DDC_CONFIG_TYPE_MODE_AUX,
+ GPIO_DDC_CONFIG_TYPE_MODE_I2C,
+ GPIO_DDC_CONFIG_TYPE_POLL_FOR_CONNECT,
+ GPIO_DDC_CONFIG_TYPE_POLL_FOR_DISCONNECT,
+ GPIO_DDC_CONFIG_TYPE_DISABLE_POLLING
+};
+
+struct gpio_ddc_config {
+ enum gpio_ddc_config_type type;
+ bool data_en_bit_present;
+ bool clock_en_bit_present;
+};
+
+/* HPD configuration */
+
+struct gpio_hpd_config {
+ uint32_t delay_on_connect; /* milliseconds */
+ uint32_t delay_on_disconnect; /* milliseconds */
+};
+
+struct gpio_generic_mux_config {
+ bool enable_output_from_mux;
+ enum gpio_signal_source mux_select;
+ enum gpio_stereo_source stereo_select;
+};
+
+enum gpio_gsl_mux_config_type {
+ GPIO_GSL_MUX_CONFIG_TYPE_DISABLE,
+ GPIO_GSL_MUX_CONFIG_TYPE_TIMING_SYNC,
+ GPIO_GSL_MUX_CONFIG_TYPE_FLIP_SYNC
+};
+
+struct gpio_gsl_mux_config {
+ enum gpio_gsl_mux_config_type type;
+ /* Actually sync_source type,
+ * however we want to avoid inter-component includes here */
+ uint32_t gsl_group;
+};
+
+struct gpio_config_data {
+ enum gpio_config_type type;
+ union {
+ struct gpio_ddc_config ddc;
+ struct gpio_hpd_config hpd;
+ struct gpio_generic_mux_config generic_mux;
+ struct gpio_gsl_mux_config gsl_mux;
+ } config;
+};
+
+struct gpio_ddc_hw_info {
+ bool hw_supported;
+ uint32_t ddc_channel;
+};
+
+struct gpio_ddc_open_options {
+ bool en_bit_present;
+};
+
+#endif
diff --git a/drivers/gpu/drm/amd/dal/include/irq_interface.h b/drivers/gpu/drm/amd/dal/include/irq_interface.h
new file mode 100644
index 000000000000..0655f0f29e41
--- /dev/null
+++ b/drivers/gpu/drm/amd/dal/include/irq_interface.h
@@ -0,0 +1,53 @@
+/*
+ * 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_INTERFACE_H__
+#define __DAL_IRQ_INTERFACE_H__
+
+#include "gpio_types.h"
+
+struct irq;
+
+enum gpio_result dal_irq_open(
+ struct irq *irq);
+
+enum gpio_result dal_irq_get_value(
+ const struct irq *irq,
+ uint32_t *value);
+
+enum dal_irq_source dal_irq_get_source(
+ const struct irq *irq);
+
+enum dal_irq_source dal_irq_get_rx_source(
+ const struct irq *irq);
+
+enum gpio_result dal_irq_setup_hpd_filter(
+ struct irq *irq,
+ struct gpio_hpd_config *config);
+
+void dal_irq_close(
+ struct irq *irq);
+
+#endif