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