diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/gpio')
25 files changed, 1294 insertions, 125 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/Makefile b/drivers/gpu/drm/amd/display/dc/gpio/Makefile index c3d92878875d..b3062275711e 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/Makefile +++ b/drivers/gpu/drm/amd/display/dc/gpio/Makefile @@ -24,7 +24,7 @@ # It provides the control and status of HW GPIO pins. GPIO = gpio_base.o gpio_service.o hw_factory.o \ - hw_gpio.o hw_hpd.o hw_ddc.o hw_translate.o + hw_gpio.o hw_hpd.o hw_ddc.o hw_generic.o hw_translate.o AMD_DAL_GPIO = $(addprefix $(AMDDALPATH)/dc/gpio/,$(GPIO)) @@ -80,6 +80,13 @@ AMD_DAL_GPIO_DCN20 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn20/,$(GPIO_DCN20)) AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCN20) endif +ifdef CONFIG_DRM_AMD_DC_DCN2_1 +GPIO_DCN21 = hw_translate_dcn21.o hw_factory_dcn21.o + +AMD_DAL_GPIO_DCN21 = $(addprefix $(AMDDALPATH)/dc/gpio/dcn21/,$(GPIO_DCN21)) + +AMD_DISPLAY_FILES += $(AMD_DAL_GPIO_DCN21) +endif ############################################################################### # Diagnostics on FPGA ############################################################################### diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dce110/hw_factory_dce110.c b/drivers/gpu/drm/amd/display/dc/gpio/dce110/hw_factory_dce110.c index 20d81bca119c..66e4841f41e4 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/dce110/hw_factory_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/dce110/hw_factory_dce110.c @@ -24,9 +24,15 @@ */ #include "dm_services.h" + #include "include/gpio_types.h" #include "../hw_factory.h" +#include "../hw_gpio.h" +#include "../hw_ddc.h" +#include "../hw_hpd.h" +#include "../hw_generic.h" + #include "hw_factory_dce110.h" #include "dce/dce_11_0_d.h" @@ -143,12 +149,12 @@ static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en) } static const struct hw_factory_funcs funcs = { - .create_ddc_data = dal_hw_ddc_create, - .create_ddc_clock = dal_hw_ddc_create, - .create_generic = NULL, - .create_hpd = dal_hw_hpd_create, - .create_sync = NULL, - .create_gsl = NULL, + .init_ddc_data = dal_hw_ddc_init, + .init_generic = NULL, + .init_hpd = dal_hw_hpd_init, + .get_ddc_pin = dal_hw_ddc_get_pin, + .get_hpd_pin = dal_hw_hpd_get_pin, + .get_generic_pin = NULL, .define_hpd_registers = define_hpd_registers, .define_ddc_registers = define_ddc_registers }; diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c b/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c index ea3f888e5c65..cf98aa827a9a 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/dce120/hw_factory_dce120.c @@ -27,10 +27,10 @@ #include "include/gpio_types.h" #include "../hw_factory.h" - #include "../hw_gpio.h" #include "../hw_ddc.h" #include "../hw_hpd.h" +#include "../hw_generic.h" #include "hw_factory_dce120.h" @@ -164,12 +164,12 @@ static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en) /* fucntion table */ static const struct hw_factory_funcs funcs = { - .create_ddc_data = dal_hw_ddc_create, - .create_ddc_clock = dal_hw_ddc_create, - .create_generic = NULL, - .create_hpd = dal_hw_hpd_create, - .create_sync = NULL, - .create_gsl = NULL, + .init_ddc_data = dal_hw_ddc_init, + .init_generic = NULL, + .init_hpd = dal_hw_hpd_init, + .get_ddc_pin = dal_hw_ddc_get_pin, + .get_hpd_pin = dal_hw_hpd_get_pin, + .get_generic_pin = NULL, .define_hpd_registers = define_hpd_registers, .define_ddc_registers = define_ddc_registers }; diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dce80/hw_factory_dce80.c b/drivers/gpu/drm/amd/display/dc/gpio/dce80/hw_factory_dce80.c index 48b67866377e..496d3ffb74bb 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/dce80/hw_factory_dce80.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/dce80/hw_factory_dce80.c @@ -32,10 +32,12 @@ #include "../hw_gpio.h" #include "../hw_ddc.h" #include "../hw_hpd.h" +#include "../hw_generic.h" #include "dce/dce_8_0_d.h" #include "dce/dce_8_0_sh_mask.h" + #define REG(reg_name)\ mm ## reg_name @@ -147,12 +149,12 @@ static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en) } static const struct hw_factory_funcs funcs = { - .create_ddc_data = dal_hw_ddc_create, - .create_ddc_clock = dal_hw_ddc_create, - .create_generic = NULL, - .create_hpd = dal_hw_hpd_create, - .create_sync = NULL, - .create_gsl = NULL, + .init_ddc_data = dal_hw_ddc_init, + .init_generic = NULL, + .init_hpd = dal_hw_hpd_init, + .get_ddc_pin = dal_hw_ddc_get_pin, + .get_hpd_pin = dal_hw_hpd_get_pin, + .get_generic_pin = NULL, .define_hpd_registers = define_hpd_registers, .define_ddc_registers = define_ddc_registers }; diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c index 32aa47a04a0d..b38c96c9fed3 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_factory_dcn10.c @@ -31,6 +31,7 @@ #include "../hw_gpio.h" #include "../hw_ddc.h" #include "../hw_hpd.h" +#include "../hw_generic.h" #include "hw_factory_dcn10.h" @@ -121,6 +122,42 @@ static const struct ddc_sh_mask ddc_mask = { DDC_MASK_SH_LIST(_MASK) }; +#include "../generic_regs.h" + +/* set field name */ +#define SF_GENERIC(reg_name, field_name, post_fix)\ + .field_name = reg_name ## __ ## field_name ## post_fix + +#define generic_regs(id) \ +{\ + GENERIC_REG_LIST(id)\ +} + +static const struct generic_registers generic_regs[] = { + generic_regs(A), + generic_regs(B), +}; + +static const struct generic_sh_mask generic_shift[] = { + GENERIC_MASK_SH_LIST(__SHIFT, A), + GENERIC_MASK_SH_LIST(__SHIFT, B), +}; + +static const struct generic_sh_mask generic_mask[] = { + GENERIC_MASK_SH_LIST(_MASK, A), + GENERIC_MASK_SH_LIST(_MASK, B), +}; + +static void define_generic_registers(struct hw_gpio_pin *pin, uint32_t en) +{ + struct hw_generic *generic = HW_GENERIC_FROM_BASE(pin); + + generic->regs = &generic_regs[en]; + generic->shifts = &generic_shift[en]; + generic->masks = &generic_mask[en]; + generic->base.regs = &generic_regs[en].gpio; +} + static void define_ddc_registers( struct hw_gpio_pin *pin, uint32_t en) @@ -159,14 +196,15 @@ static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en) /* fucntion table */ static const struct hw_factory_funcs funcs = { - .create_ddc_data = dal_hw_ddc_create, - .create_ddc_clock = dal_hw_ddc_create, - .create_generic = NULL, - .create_hpd = dal_hw_hpd_create, - .create_sync = NULL, - .create_gsl = NULL, + .init_ddc_data = dal_hw_ddc_init, + .init_generic = dal_hw_generic_init, + .init_hpd = dal_hw_hpd_init, + .get_ddc_pin = dal_hw_ddc_get_pin, + .get_hpd_pin = dal_hw_hpd_get_pin, + .get_generic_pin = dal_hw_generic_get_pin, .define_hpd_registers = define_hpd_registers, - .define_ddc_registers = define_ddc_registers + .define_ddc_registers = define_ddc_registers, + .define_generic_registers = define_generic_registers }; /* * dal_hw_factory_dcn10_init diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c index abd76d855375..43a440385b43 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_factory_dcn20.c @@ -31,6 +31,7 @@ #include "../hw_gpio.h" #include "../hw_ddc.h" #include "../hw_hpd.h" +#include "../hw_generic.h" #include "hw_factory_dcn20.h" @@ -138,6 +139,32 @@ static const struct ddc_sh_mask ddc_mask[] = { DDC_MASK_SH_LIST_DCN2(_MASK, 6) }; +#include "../generic_regs.h" + +/* set field name */ +#define SF_GENERIC(reg_name, field_name, post_fix)\ + .field_name = reg_name ## __ ## field_name ## post_fix + +#define generic_regs(id) \ +{\ + GENERIC_REG_LIST(id)\ +} + +static const struct generic_registers generic_regs[] = { + generic_regs(A), + generic_regs(B), +}; + +static const struct generic_sh_mask generic_shift[] = { + GENERIC_MASK_SH_LIST(__SHIFT, A), + GENERIC_MASK_SH_LIST(__SHIFT, B), +}; + +static const struct generic_sh_mask generic_mask[] = { + GENERIC_MASK_SH_LIST(_MASK, A), + GENERIC_MASK_SH_LIST(_MASK, B), +}; + static void define_ddc_registers( struct hw_gpio_pin *pin, uint32_t en) @@ -173,17 +200,27 @@ static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en) hpd->base.regs = &hpd_regs[en].gpio; } +static void define_generic_registers(struct hw_gpio_pin *pin, uint32_t en) +{ + struct hw_generic *generic = HW_GENERIC_FROM_BASE(pin); + + generic->regs = &generic_regs[en]; + generic->shifts = &generic_shift[en]; + generic->masks = &generic_mask[en]; + generic->base.regs = &generic_regs[en].gpio; +} /* fucntion table */ static const struct hw_factory_funcs funcs = { - .create_ddc_data = dal_hw_ddc_create, - .create_ddc_clock = dal_hw_ddc_create, - .create_generic = NULL, - .create_hpd = dal_hw_hpd_create, - .create_sync = NULL, - .create_gsl = NULL, + .init_ddc_data = dal_hw_ddc_init, + .init_generic = dal_hw_generic_init, + .init_hpd = dal_hw_hpd_init, + .get_ddc_pin = dal_hw_ddc_get_pin, + .get_hpd_pin = dal_hw_hpd_get_pin, + .get_generic_pin = dal_hw_generic_get_pin, .define_hpd_registers = define_hpd_registers, - .define_ddc_registers = define_ddc_registers + .define_ddc_registers = define_ddc_registers, + .define_generic_registers = define_generic_registers, }; /* * dal_hw_factory_dcn10_init diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_translate_dcn20.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_translate_dcn20.c index b393cc13298a..915e896e0e91 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_translate_dcn20.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_translate_dcn20.c @@ -71,7 +71,7 @@ static bool offset_to_id( { switch (offset) { /* GENERIC */ - case REG(DC_GENERICA): + case REG(DC_GPIO_GENERIC_A): *id = GPIO_ID_GENERIC; switch (mask) { case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK: diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_factory_dcn21.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_factory_dcn21.c new file mode 100644 index 000000000000..34485d9de78a --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_factory_dcn21.c @@ -0,0 +1,210 @@ +/* + * 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 + * + */ +#if defined(CONFIG_DRM_AMD_DC_DCN2_0) +#include "dm_services.h" +#include "include/gpio_types.h" +#include "../hw_factory.h" + + +#include "../hw_gpio.h" +#include "../hw_ddc.h" +#include "../hw_hpd.h" +#include "../hw_generic.h" + +#include "hw_factory_dcn21.h" + + +#include "dcn/dcn_2_1_0_offset.h" +#include "dcn/dcn_2_1_0_sh_mask.h" +#include "renoir_ip_offset.h" + + +#include "reg_helper.h" +#include "../hpd_regs.h" +/* begin ********************* + * macros to expend register list macro defined in HW object header file */ + +/* DCN */ +#define block HPD +#define reg_num 0 + +#undef BASE_INNER +#define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg + +#define BASE(seg) BASE_INNER(seg) + + + +#define REG(reg_name)\ + BASE(mm ## reg_name ## _BASE_IDX) + mm ## reg_name + +#define SF_HPD(reg_name, field_name, post_fix)\ + .field_name = HPD0_ ## reg_name ## __ ## field_name ## post_fix + +#define REGI(reg_name, block, id)\ + BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ + mm ## block ## id ## _ ## reg_name + +#define SF(reg_name, field_name, post_fix)\ + .field_name = reg_name ## __ ## field_name ## post_fix + +/* macros to expend register list macro defined in HW object header file + * end *********************/ + + + +#define hpd_regs(id) \ +{\ + HPD_REG_LIST(id)\ +} + +static const struct hpd_registers hpd_regs[] = { + hpd_regs(0), + hpd_regs(1), + hpd_regs(2), + hpd_regs(3), + hpd_regs(4), +}; + +static const struct hpd_sh_mask hpd_shift = { + HPD_MASK_SH_LIST(__SHIFT) +}; + +static const struct hpd_sh_mask hpd_mask = { + HPD_MASK_SH_LIST(_MASK) +}; + +#include "../ddc_regs.h" + + /* set field name */ +#define SF_DDC(reg_name, field_name, post_fix)\ + .field_name = reg_name ## __ ## field_name ## post_fix + +static const struct ddc_registers ddc_data_regs_dcn[] = { + ddc_data_regs_dcn2(1), + ddc_data_regs_dcn2(2), + ddc_data_regs_dcn2(3), + ddc_data_regs_dcn2(4), + ddc_data_regs_dcn2(5), +}; + +static const struct ddc_registers ddc_clk_regs_dcn[] = { + ddc_clk_regs_dcn2(1), + ddc_clk_regs_dcn2(2), + ddc_clk_regs_dcn2(3), + ddc_clk_regs_dcn2(4), + ddc_clk_regs_dcn2(5), +}; + +static const struct ddc_sh_mask ddc_shift[] = { + DDC_MASK_SH_LIST_DCN2(__SHIFT, 1), + DDC_MASK_SH_LIST_DCN2(__SHIFT, 2), + DDC_MASK_SH_LIST_DCN2(__SHIFT, 3), + DDC_MASK_SH_LIST_DCN2(__SHIFT, 4), + DDC_MASK_SH_LIST_DCN2(__SHIFT, 5), + DDC_MASK_SH_LIST_DCN2(__SHIFT, 6) +}; + +static const struct ddc_sh_mask ddc_mask[] = { + DDC_MASK_SH_LIST_DCN2(_MASK, 1), + DDC_MASK_SH_LIST_DCN2(_MASK, 2), + DDC_MASK_SH_LIST_DCN2(_MASK, 3), + DDC_MASK_SH_LIST_DCN2(_MASK, 4), + DDC_MASK_SH_LIST_DCN2(_MASK, 5), + DDC_MASK_SH_LIST_DCN2(_MASK, 6) +}; + +static void define_ddc_registers( + struct hw_gpio_pin *pin, + uint32_t en) +{ + struct hw_ddc *ddc = HW_DDC_FROM_BASE(pin); + + switch (pin->id) { + case GPIO_ID_DDC_DATA: + ddc->regs = &ddc_data_regs_dcn[en]; + ddc->base.regs = &ddc_data_regs_dcn[en].gpio; + break; + case GPIO_ID_DDC_CLOCK: + ddc->regs = &ddc_clk_regs_dcn[en]; + ddc->base.regs = &ddc_clk_regs_dcn[en].gpio; + break; + default: + ASSERT_CRITICAL(false); + return; + } + + ddc->shifts = &ddc_shift[en]; + ddc->masks = &ddc_mask[en]; + +} + +static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en) +{ + struct hw_hpd *hpd = HW_HPD_FROM_BASE(pin); + + hpd->regs = &hpd_regs[en]; + hpd->shifts = &hpd_shift; + hpd->masks = &hpd_mask; + hpd->base.regs = &hpd_regs[en].gpio; +} + + +/* fucntion table */ +static const struct hw_factory_funcs funcs = { + .init_ddc_data = dal_hw_ddc_init, + .init_generic = dal_hw_generic_init, + .init_hpd = dal_hw_hpd_init, + .get_ddc_pin = dal_hw_ddc_get_pin, + .get_hpd_pin = dal_hw_hpd_get_pin, + .get_generic_pin = dal_hw_generic_get_pin, + .define_hpd_registers = define_hpd_registers, + .define_ddc_registers = define_ddc_registers +}; +/* + * dal_hw_factory_dcn10_init + * + * @brief + * Initialize HW factory function pointers and pin info + * + * @param + * struct hw_factory *factory - [out] struct of function pointers + */ +void dal_hw_factory_dcn21_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] = 4; + factory->number_of_pins[GPIO_ID_HPD] = 6; + factory->number_of_pins[GPIO_ID_GPIO_PAD] = 28; + factory->number_of_pins[GPIO_ID_VIP_PAD] = 0; + factory->number_of_pins[GPIO_ID_SYNC] = 0; + factory->number_of_pins[GPIO_ID_GSL] = 0;/*add this*/ + + factory->funcs = &funcs; +} + +#endif diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_factory_dcn21.h b/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_factory_dcn21.h new file mode 100644 index 000000000000..2443f9e7afbf --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_factory_dcn21.h @@ -0,0 +1,33 @@ +/* + * Copyright 2018 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 + * + */ +#if defined(CONFIG_DRM_AMD_DC_DCN2_1) +#ifndef __DAL_HW_FACTORY_DCN21_H__ +#define __DAL_HW_FACTORY_DCN21_H__ + +/* Initialize HW factory function pointers and pin info */ +void dal_hw_factory_dcn21_init(struct hw_factory *factory); + +#endif /* __DAL_HW_FACTORY_DCN20_H__ */ +#endif diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_translate_dcn21.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_translate_dcn21.c new file mode 100644 index 000000000000..ad7c43746291 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_translate_dcn21.c @@ -0,0 +1,386 @@ +/* + * Copyright 2018 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 + */ +#if defined(CONFIG_DRM_AMD_DC_DCN2_0) +#include "hw_translate_dcn21.h" + +#include "dm_services.h" +#include "include/gpio_types.h" +#include "../hw_translate.h" + +#include "dcn/dcn_2_1_0_offset.h" +#include "dcn/dcn_2_1_0_sh_mask.h" +#include "renoir_ip_offset.h" + + + + +/* begin ********************* + * macros to expend register list macro defined in HW object header file */ + +/* DCN */ +#define block HPD +#define reg_num 0 + +#undef BASE_INNER +#define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg + +#define BASE(seg) BASE_INNER(seg) + +#undef REG +#define REG(reg_name)\ + BASE(mm ## reg_name ## _BASE_IDX) + mm ## reg_name +#define SF_HPD(reg_name, field_name, post_fix)\ + .field_name = reg_name ## __ ## field_name ## post_fix + + +/* macros to expend register list macro defined in HW object header file + * end *********************/ + + +static bool offset_to_id( + uint32_t offset, + uint32_t mask, + enum gpio_id *id, + uint32_t *en) +{ + switch (offset) { + /* GENERIC */ + case REG(DC_GENERICA): + *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); +#ifdef PALLADIUM_SUPPORTED + *en = GPIO_DDC_LINE_DDC1; + return true; +#endif + return false; + } + break; + /* HPD */ + case REG(DC_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; + /* REG(DC_GPIO_GENLK_MASK */ + case REG(DC_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 REG(DC_GPIO_DDC1_A): + *en = GPIO_DDC_LINE_DDC1; + return true; + case REG(DC_GPIO_DDC2_A): + *en = GPIO_DDC_LINE_DDC2; + return true; + case REG(DC_GPIO_DDC3_A): + *en = GPIO_DDC_LINE_DDC3; + return true; + case REG(DC_GPIO_DDC4_A): + *en = GPIO_DDC_LINE_DDC4; + return true; + case REG(DC_GPIO_DDC5_A): + *en = GPIO_DDC_LINE_DDC5; + return true; + case REG(DC_GPIO_DDCVGA_A): + *en = GPIO_DDC_LINE_DDC_VGA; + return true; + +// case REG(DC_GPIO_I2CPAD_A): not exit +// case REG(DC_GPIO_PWRSEQ_A): +// case REG(DC_GPIO_PAD_STRENGTH_1): +// case REG(DC_GPIO_PAD_STRENGTH_2): +// case REG(DC_GPIO_DEBUG): + /* UNEXPECTED */ + default: +// case REG(DC_GPIO_SYNCA_A): not exist +#ifdef PALLADIUM_SUPPORTED + *id = GPIO_ID_HPD; + *en = GPIO_DDC_LINE_DDC1; + return true; +#endif + 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_DDC5_A__DC_GPIO_DDC5DATA_A_MASK; + switch (en) { + case GPIO_DDC_LINE_DDC1: + info->offset = REG(DC_GPIO_DDC1_A); + break; + case GPIO_DDC_LINE_DDC2: + info->offset = REG(DC_GPIO_DDC2_A); + break; + case GPIO_DDC_LINE_DDC3: + info->offset = REG(DC_GPIO_DDC3_A); + break; + case GPIO_DDC_LINE_DDC4: + info->offset = REG(DC_GPIO_DDC4_A); + break; + case GPIO_DDC_LINE_DDC5: + info->offset = REG(DC_GPIO_DDC5_A); + break; + case GPIO_DDC_LINE_DDC_VGA: + info->offset = REG(DC_GPIO_DDCVGA_A); + break; + case GPIO_DDC_LINE_I2C_PAD: + default: + ASSERT_CRITICAL(false); + result = false; + } + break; + case GPIO_ID_DDC_CLOCK: + info->mask = DC_GPIO_DDC5_A__DC_GPIO_DDC5CLK_A_MASK; + switch (en) { + case GPIO_DDC_LINE_DDC1: + info->offset = REG(DC_GPIO_DDC1_A); + break; + case GPIO_DDC_LINE_DDC2: + info->offset = REG(DC_GPIO_DDC2_A); + break; + case GPIO_DDC_LINE_DDC3: + info->offset = REG(DC_GPIO_DDC3_A); + break; + case GPIO_DDC_LINE_DDC4: + info->offset = REG(DC_GPIO_DDC4_A); + break; + case GPIO_DDC_LINE_DDC5: + info->offset = REG(DC_GPIO_DDC5_A); + break; + case GPIO_DDC_LINE_DDC_VGA: + info->offset = REG(DC_GPIO_DDCVGA_A); + break; + case GPIO_DDC_LINE_I2C_PAD: + default: + ASSERT_CRITICAL(false); + result = false; + } + break; + case GPIO_ID_GENERIC: + info->offset = REG(DC_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 = REG(DC_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); +#ifdef PALLADIUM_SUPPORTED + info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK; + result = true; +#endif + result = false; + } + break; + case GPIO_ID_GSL: + switch (en) { + case GPIO_GSL_GENLOCK_CLOCK: + /*not implmented*/ + ASSERT_CRITICAL(false); + result = false; + break; + case GPIO_GSL_GENLOCK_VSYNC: + /*not implmented*/ + ASSERT_CRITICAL(false); + result = false; + break; + case GPIO_GSL_SWAPLOCK_A: + /*not implmented*/ + ASSERT_CRITICAL(false); + result = false; + break; + case GPIO_GSL_SWAPLOCK_B: + /*not implmented*/ + ASSERT_CRITICAL(false); + result = false; + + break; + default: + ASSERT_CRITICAL(false); + result = false; + } + break; + case GPIO_ID_SYNC: + 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_dcn10_init + * + * @brief + * Initialize Hw translate function pointers. + * + * @param + * struct hw_translate *tr - [out] struct of function pointers + * + */ +void dal_hw_translate_dcn21_init(struct hw_translate *tr) +{ + tr->funcs = &funcs; +} + +#endif diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_translate_dcn21.h b/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_translate_dcn21.h new file mode 100644 index 000000000000..2bfaac24c574 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_translate_dcn21.h @@ -0,0 +1,35 @@ +/* + * Copyright 2018 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 + * + */ +#if defined(CONFIG_DRM_AMD_DC_DCN2_1) +#ifndef __DAL_HW_TRANSLATE_DCN21_H__ +#define __DAL_HW_TRANSLATE_DCN21_H__ + +struct hw_translate; + +/* Initialize Hw translate function pointers */ +void dal_hw_translate_dcn21_init(struct hw_translate *tr); + +#endif /* __DAL_HW_TRANSLATE_DCN21_H__ */ +#endif diff --git a/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c b/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c index 26695b963c58..df68430aeb0c 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/diagnostics/hw_factory_diag.c @@ -38,15 +38,13 @@ #include "../hw_gpio.h" #include "../hw_ddc.h" #include "../hw_hpd.h" +#include "../hw_generic.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_sync = NULL, - .create_gsl = NULL, + .init_ddc_data = NULL, + .init_generic = NULL, + .init_hpd = NULL, }; void dal_hw_factory_diag_fpga_init(struct hw_factory *factory) diff --git a/drivers/gpu/drm/amd/display/dc/gpio/generic_regs.h b/drivers/gpu/drm/amd/display/dc/gpio/generic_regs.h new file mode 100644 index 000000000000..8c05295c05c2 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/gpio/generic_regs.h @@ -0,0 +1,66 @@ +/* + * 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 DRIVERS_GPU_DRM_AMD_DC_DEV_DC_GPIO_GENERIC_REGS_H_ +#define DRIVERS_GPU_DRM_AMD_DC_DEV_DC_GPIO_GENERIC_REGS_H_ + +#include "gpio_regs.h" + +#define GENERIC_GPIO_REG_LIST_ENTRY(type, cd, id) \ + .type ## _reg = REG(DC_GPIO_GENERIC_## type),\ + .type ## _mask = DC_GPIO_GENERIC_ ## type ## __DC_GPIO_GENERIC ## id ## _ ## type ## _MASK,\ + .type ## _shift = DC_GPIO_GENERIC_ ## type ## __DC_GPIO_GENERIC ## id ## _ ## type ## __SHIFT + +#define GENERIC_GPIO_REG_LIST(id) \ + {\ + GENERIC_GPIO_REG_LIST_ENTRY(MASK, cd, id),\ + GENERIC_GPIO_REG_LIST_ENTRY(A, cd, id),\ + GENERIC_GPIO_REG_LIST_ENTRY(EN, cd, id),\ + GENERIC_GPIO_REG_LIST_ENTRY(Y, cd, id)\ + } + +#define GENERIC_REG_LIST(id) \ + GENERIC_GPIO_REG_LIST(id), \ + .mux = REG(DC_GENERIC ## id),\ + +#define GENERIC_MASK_SH_LIST(mask_sh, cd) \ + {(DC_GENERIC ## cd ##__GENERIC ## cd ##_EN## mask_sh),\ + (DC_GENERIC ## cd ##__GENERIC ## cd ##_SEL## mask_sh)} + +struct generic_registers { + struct gpio_registers gpio; + uint32_t mux; +}; + +struct generic_sh_mask { + /* enable */ + uint32_t GENERIC_EN; + /* select */ + uint32_t GENERIC_SEL; + +}; + + +#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_GPIO_GENERIC_REGS_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c index d03b38e80d9b..f8f85490e77e 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c @@ -67,10 +67,14 @@ enum gpio_result dal_gpio_open_ex( return GPIO_RESULT_ALREADY_OPENED; } + // No action if allocation failed during gpio construct + if (!gpio->hw_container.ddc) { + ASSERT_CRITICAL(false); + return GPIO_RESULT_NON_SPECIFIC_ERROR; + } gpio->mode = mode; - return dal_gpio_service_open( - gpio->service, gpio->id, gpio->en, mode, &gpio->pin); + return dal_gpio_service_open(gpio); } enum gpio_result dal_gpio_get_value( @@ -231,6 +235,21 @@ enum gpio_pin_output_state dal_gpio_get_output_state( return gpio->output_state; } +struct hw_ddc *dal_gpio_get_ddc(struct gpio *gpio) +{ + return gpio->hw_container.ddc; +} + +struct hw_hpd *dal_gpio_get_hpd(struct gpio *gpio) +{ + return gpio->hw_container.hpd; +} + +struct hw_generic *dal_gpio_get_generic(struct gpio *gpio) +{ + return gpio->hw_container.generic; +} + void dal_gpio_close( struct gpio *gpio) { @@ -267,6 +286,30 @@ struct gpio *dal_gpio_create( gpio->mode = GPIO_MODE_UNKNOWN; gpio->output_state = output_state; + //initialize hw_container union based on id + switch (gpio->id) { + case GPIO_ID_DDC_DATA: + gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en); + break; + case GPIO_ID_DDC_CLOCK: + gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en); + break; + case GPIO_ID_GENERIC: + gpio->service->factory.funcs->init_generic(&gpio->hw_container.generic, service->ctx, id, en); + break; + case GPIO_ID_HPD: + gpio->service->factory.funcs->init_hpd(&gpio->hw_container.hpd, service->ctx, id, en); + break; + // TODO: currently gpio for sync and gsl does not get created, might need it later + case GPIO_ID_SYNC: + break; + case GPIO_ID_GSL: + break; + default: + ASSERT_CRITICAL(false); + gpio->pin = NULL; + } + return gpio; } @@ -280,6 +323,33 @@ void dal_gpio_destroy( dal_gpio_close(*gpio); + switch ((*gpio)->id) { + case GPIO_ID_DDC_DATA: + kfree((*gpio)->hw_container.ddc); + (*gpio)->hw_container.ddc = NULL; + break; + case GPIO_ID_DDC_CLOCK: + //TODO: might want to change it to init_ddc_clock + kfree((*gpio)->hw_container.ddc); + (*gpio)->hw_container.ddc = NULL; + break; + case GPIO_ID_GENERIC: + kfree((*gpio)->hw_container.generic); + (*gpio)->hw_container.generic = NULL; + break; + case GPIO_ID_HPD: + kfree((*gpio)->hw_container.hpd); + (*gpio)->hw_container.hpd = NULL; + break; + // TODO: currently gpio for sync and gsl does not get created, might need it later + case GPIO_ID_SYNC: + break; + case GPIO_ID_GSL: + break; + default: + break; + } + kfree(*gpio); *gpio = NULL; diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c index a7fab44f66b6..d03165e71dc6 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c @@ -141,6 +141,58 @@ struct gpio *dal_gpio_service_create_irq( return dal_gpio_create_irq(service, id, en); } +struct gpio *dal_gpio_service_create_generic_mux( + struct gpio_service *service, + uint32_t offset, + uint32_t mask) +{ + enum gpio_id id; + uint32_t en; + struct gpio *generic; + + if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) { + ASSERT_CRITICAL(false); + return NULL; + } + + generic = dal_gpio_create( + service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT); + + return generic; +} + +void dal_gpio_destroy_generic_mux( + struct gpio **mux) +{ + if (!mux || !*mux) { + ASSERT_CRITICAL(false); + return; + } + + dal_gpio_close(*mux); + dal_gpio_destroy(mux); + kfree(*mux); + + *mux = NULL; +} + +struct gpio_pin_info dal_gpio_get_generic_pin_info( + struct gpio_service *service, + enum gpio_id id, + uint32_t en) +{ + struct gpio_pin_info pin; + + if (service->translate.funcs->id_to_offset) { + service->translate.funcs->id_to_offset(id, en, &pin); + } else { + pin.mask = 0xFFFFFFFF; + pin.offset = 0xFFFFFFFF; + } + + return pin; +} + void dal_gpio_service_destroy( struct gpio_service **ptr) { @@ -165,6 +217,21 @@ void dal_gpio_service_destroy( *ptr = NULL; } +enum gpio_result dal_mux_setup_config( + struct gpio *mux, + struct gpio_generic_mux_config *config) +{ + struct gpio_config_data config_data; + + if (!config) + return GPIO_RESULT_INVALID_DATA; + + config_data.config.generic_mux = *config; + config_data.type = GPIO_CONFIG_TYPE_GENERIC_MUX; + + return dal_gpio_set_config(mux, &config_data); +} + /* * @brief * Private API. @@ -223,13 +290,15 @@ enum gpio_result dal_gpio_service_unlock( } enum gpio_result dal_gpio_service_open( - struct gpio_service *service, - enum gpio_id id, - uint32_t en, - enum gpio_mode mode, - struct hw_gpio_pin **ptr) + struct gpio *gpio) { - struct hw_gpio_pin *pin; + struct gpio_service *service = gpio->service; + enum gpio_id id = gpio->id; + uint32_t en = gpio->en; + enum gpio_mode mode = gpio->mode; + + struct hw_gpio_pin **pin = &gpio->pin; + if (!service->busyness[id]) { ASSERT_CRITICAL(false); @@ -243,50 +312,43 @@ enum gpio_result dal_gpio_service_open( switch (id) { case GPIO_ID_DDC_DATA: - pin = service->factory.funcs->create_ddc_data( - service->ctx, id, en); - service->factory.funcs->define_ddc_registers(pin, en); + *pin = service->factory.funcs->get_ddc_pin(gpio); + service->factory.funcs->define_ddc_registers(*pin, en); break; case GPIO_ID_DDC_CLOCK: - pin = service->factory.funcs->create_ddc_clock( - service->ctx, id, en); - service->factory.funcs->define_ddc_registers(pin, en); + *pin = service->factory.funcs->get_ddc_pin(gpio); + service->factory.funcs->define_ddc_registers(*pin, en); break; case GPIO_ID_GENERIC: - pin = service->factory.funcs->create_generic( - service->ctx, id, en); + *pin = service->factory.funcs->get_generic_pin(gpio); + service->factory.funcs->define_generic_registers(*pin, en); break; case GPIO_ID_HPD: - pin = service->factory.funcs->create_hpd( - service->ctx, id, en); - service->factory.funcs->define_hpd_registers(pin, en); + *pin = service->factory.funcs->get_hpd_pin(gpio); + service->factory.funcs->define_hpd_registers(*pin, en); break; + + //TODO: gsl and sync support? create_sync and create_gsl are NULL 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) { + if (!*pin) { ASSERT_CRITICAL(false); return GPIO_RESULT_NON_SPECIFIC_ERROR; } - if (!pin->funcs->open(pin, mode)) { + if (!(*pin)->funcs->open(*pin, mode)) { ASSERT_CRITICAL(false); - dal_gpio_service_close(service, &pin); + dal_gpio_service_close(service, pin); return GPIO_RESULT_OPEN_FAILED; } set_pin_busy(service, id, en); - *ptr = pin; return GPIO_RESULT_OK; } @@ -308,11 +370,10 @@ void dal_gpio_service_close( pin->funcs->close(pin); - pin->funcs->destroy(ptr); + *ptr = NULL; } } - enum dc_irq_source dal_irq_get_source( const struct gpio *irq) { diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h index 0c678af75331..b9775a131ecd 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h +++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.h @@ -42,11 +42,7 @@ struct gpio_service { }; enum gpio_result dal_gpio_service_open( - struct gpio_service *service, - enum gpio_id id, - uint32_t en, - enum gpio_mode mode, - struct hw_gpio_pin **ptr); + struct gpio *gpio); void dal_gpio_service_close( struct gpio_service *service, diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c index 408857d19c84..1c12961f6472 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c @@ -28,6 +28,7 @@ #include "dm_services.h" +#include "include/gpio_interface.h" #include "include/gpio_types.h" #include "hw_gpio.h" #include "hw_ddc.h" @@ -45,6 +46,8 @@ #define REG(reg)\ (ddc->regs->reg) +struct gpio; + static void destruct( struct hw_ddc *pin) { @@ -227,24 +230,29 @@ static void construct( ddc->base.base.funcs = &funcs; } -struct hw_gpio_pin *dal_hw_ddc_create( +void dal_hw_ddc_init( + struct hw_ddc **hw_ddc, struct dc_context *ctx, enum gpio_id id, uint32_t en) { - struct hw_ddc *pin; - if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) { ASSERT_CRITICAL(false); - return NULL; + *hw_ddc = NULL; } - pin = kzalloc(sizeof(struct hw_ddc), GFP_KERNEL); - if (!pin) { + *hw_ddc = kzalloc(sizeof(struct hw_ddc), GFP_KERNEL); + if (!*hw_ddc) { ASSERT_CRITICAL(false); - return NULL; + return; } - construct(pin, id, en, ctx); - return &pin->base.base; + construct(*hw_ddc, id, en, ctx); +} + +struct hw_gpio_pin *dal_hw_ddc_get_pin(struct gpio *gpio) +{ + struct hw_ddc *hw_ddc = dal_gpio_get_ddc(gpio); + + return &hw_ddc->base.base; } diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.h b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.h index 9690e2a885d7..cc30e65df431 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.h +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.h @@ -38,9 +38,12 @@ struct hw_ddc { #define HW_DDC_FROM_BASE(hw_gpio) \ container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_ddc, base) -struct hw_gpio_pin *dal_hw_ddc_create( +void dal_hw_ddc_init( + struct hw_ddc **hw_ddc, struct dc_context *ctx, enum gpio_id id, uint32_t en); +struct hw_gpio_pin *dal_hw_ddc_get_pin(struct gpio *gpio); + #endif diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c index 78f528f92907..fa9f1d055ec8 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.c @@ -51,6 +51,9 @@ #if defined(CONFIG_DRM_AMD_DC_DCN2_0) #include "dcn20/hw_factory_dcn20.h" #endif +#if defined(CONFIG_DRM_AMD_DC_DCN2_1) +#include "dcn21/hw_factory_dcn21.h" +#endif #include "diagnostics/hw_factory_diag.h" @@ -99,6 +102,11 @@ bool dal_hw_factory_init( dal_hw_factory_dcn20_init(factory); return true; #endif +#if defined(CONFIG_DRM_AMD_DC_DCN2_1) + case DCN_VERSION_2_1: + dal_hw_factory_dcn21_init(factory); + return true; +#endif default: ASSERT_CRITICAL(false); diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.h b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.h index 6e4dd3521935..e15b037f3bcd 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.h +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_factory.h @@ -28,41 +28,44 @@ struct hw_gpio_pin; struct hw_hpd; +struct hw_ddc; +struct hw_generic; +struct gpio; 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_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); + void (*init_ddc_data)( + struct hw_ddc **hw_ddc, + struct dc_context *ctx, + enum gpio_id id, + uint32_t en); + void (*init_generic)( + struct hw_generic **hw_generic, + struct dc_context *ctx, + enum gpio_id id, + uint32_t en); + void (*init_hpd)( + struct hw_hpd **hw_hpd, + struct dc_context *ctx, + enum gpio_id id, + uint32_t en); + struct hw_gpio_pin *(*get_hpd_pin)( + struct gpio *gpio); + struct hw_gpio_pin *(*get_ddc_pin)( + struct gpio *gpio); + struct hw_gpio_pin *(*get_generic_pin)( + struct gpio *gpio); void (*define_hpd_registers)( struct hw_gpio_pin *pin, uint32_t en); void (*define_ddc_registers)( struct hw_gpio_pin *pin, uint32_t en); + void (*define_generic_registers)( + struct hw_gpio_pin *pin, + uint32_t en); } *funcs; }; diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c new file mode 100644 index 000000000000..69b899741f6d --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c @@ -0,0 +1,138 @@ +/* + * 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 <linux/slab.h> + +#include "dm_services.h" + +#include "include/gpio_interface.h" +#include "include/gpio_types.h" +#include "hw_gpio.h" +#include "hw_generic.h" + +#include "reg_helper.h" +#include "generic_regs.h" + +#undef FN +#define FN(reg_name, field_name) \ + generic->shifts->field_name, generic->masks->field_name + +#define CTX \ + generic->base.base.ctx +#define REG(reg)\ + (generic->regs->reg) + +struct gpio; + +static void dal_hw_generic_construct( + struct hw_generic *pin, + enum gpio_id id, + uint32_t en, + struct dc_context *ctx) +{ + dal_hw_gpio_construct(&pin->base, id, en, ctx); +} + +static void dal_hw_generic_destruct( + struct hw_generic *pin) +{ + dal_hw_gpio_destruct(&pin->base); +} + +static void destroy( + struct hw_gpio_pin **ptr) +{ + struct hw_generic *generic = HW_GENERIC_FROM_BASE(*ptr); + + dal_hw_generic_destruct(generic); + + kfree(generic); + + *ptr = NULL; +} + +static enum gpio_result set_config( + struct hw_gpio_pin *ptr, + const struct gpio_config_data *config_data) +{ + struct hw_generic *generic = HW_GENERIC_FROM_BASE(ptr); + + if (!config_data) + return GPIO_RESULT_INVALID_DATA; + + REG_UPDATE_2(mux, + GENERIC_EN, config_data->config.generic_mux.enable_output_from_mux, + GENERIC_SEL, config_data->config.generic_mux.mux_select); + + return GPIO_RESULT_OK; +} + +static const struct hw_gpio_pin_funcs funcs = { + .destroy = destroy, + .open = dal_hw_gpio_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 void construct( + struct hw_generic *generic, + enum gpio_id id, + uint32_t en, + struct dc_context *ctx) +{ + dal_hw_generic_construct(generic, id, en, ctx); + generic->base.base.funcs = &funcs; +} + +void dal_hw_generic_init( + struct hw_generic **hw_generic, + struct dc_context *ctx, + enum gpio_id id, + uint32_t en) +{ + if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) { + ASSERT_CRITICAL(false); + *hw_generic = NULL; + } + + *hw_generic = kzalloc(sizeof(struct hw_generic), GFP_KERNEL); + if (!*hw_generic) { + ASSERT_CRITICAL(false); + return; + } + + construct(*hw_generic, id, en, ctx); +} + + +struct hw_gpio_pin *dal_hw_generic_get_pin(struct gpio *gpio) +{ + struct hw_generic *hw_generic = dal_gpio_get_generic(gpio); + + return &hw_generic->base.base; +} diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.h b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.h new file mode 100644 index 000000000000..bd6ffeb5e9df --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.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_generic_H__ +#define __DAL_HW_generic_H__ + +#include "generic_regs.h" +#include "hw_gpio.h" + +struct hw_generic { + struct hw_gpio base; + const struct generic_registers *regs; + const struct generic_sh_mask *shifts; + const struct generic_sh_mask *masks; +}; + +#define HW_GENERIC_FROM_BASE(hw_gpio) \ + container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_generic, base) + +void dal_hw_generic_init( + struct hw_generic **hw_generic, + struct dc_context *ctx, + enum gpio_id id, + uint32_t en); + +struct hw_gpio_pin *dal_hw_generic_get_pin(struct gpio *gpio); + +#endif diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c index 5e11d748e6f3..00c9bcf660a3 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c @@ -27,6 +27,7 @@ #include "dm_services.h" +#include "include/gpio_interface.h" #include "include/gpio_types.h" #include "hw_gpio.h" #include "hw_hpd.h" @@ -43,6 +44,8 @@ #define REG(reg)\ (hpd->regs->reg) +struct gpio; + static void dal_hw_hpd_construct( struct hw_hpd *pin, enum gpio_id id, @@ -136,29 +139,29 @@ static void construct( hpd->base.base.funcs = &funcs; } -struct hw_gpio_pin *dal_hw_hpd_create( +void dal_hw_hpd_init( + struct hw_hpd **hw_hpd, struct dc_context *ctx, enum gpio_id id, uint32_t en) { - struct hw_hpd *hpd; - - if (id != GPIO_ID_HPD) { + if ((en < GPIO_DDC_LINE_MIN) || (en > GPIO_DDC_LINE_MAX)) { ASSERT_CRITICAL(false); - return NULL; + *hw_hpd = NULL; } - if ((en < GPIO_HPD_MIN) || (en > GPIO_HPD_MAX)) { + *hw_hpd = kzalloc(sizeof(struct hw_hpd), GFP_KERNEL); + if (!*hw_hpd) { ASSERT_CRITICAL(false); - return NULL; + return; } - hpd = kzalloc(sizeof(struct hw_hpd), GFP_KERNEL); - if (!hpd) { - ASSERT_CRITICAL(false); - return NULL; - } + construct(*hw_hpd, id, en, ctx); +} + +struct hw_gpio_pin *dal_hw_hpd_get_pin(struct gpio *gpio) +{ + struct hw_hpd *hw_hpd = dal_gpio_get_hpd(gpio); - construct(hpd, id, en, ctx); - return &hpd->base.base; + return &hw_hpd->base.base; } diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.h b/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.h index 4ab7a208f781..e7d8b3bb016c 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.h +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.h @@ -38,9 +38,12 @@ struct hw_hpd { #define HW_HPD_FROM_BASE(hw_gpio) \ container_of((HW_GPIO_FROM_BASE(hw_gpio)), struct hw_hpd, base) -struct hw_gpio_pin *dal_hw_hpd_create( +void dal_hw_hpd_init( + struct hw_hpd **hw_hpd, struct dc_context *ctx, enum gpio_id id, uint32_t en); +struct hw_gpio_pin *dal_hw_hpd_get_pin(struct gpio *gpio); + #endif diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c index c35fe201d335..f2046f55d6a8 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c @@ -49,6 +49,9 @@ #if defined(CONFIG_DRM_AMD_DC_DCN2_0) #include "dcn20/hw_translate_dcn20.h" #endif +#if defined(CONFIG_DRM_AMD_DC_DCN2_1) +#include "dcn21/hw_translate_dcn21.h" +#endif #include "diagnostics/hw_translate_diag.h" @@ -94,6 +97,11 @@ bool dal_hw_translate_init( dal_hw_translate_dcn20_init(translate); return true; #endif +#if defined(CONFIG_DRM_AMD_DC_DCN2_1) + case DCN_VERSION_2_1: + dal_hw_translate_dcn21_init(translate); + return true; +#endif default: BREAK_TO_DEBUGGER(); |