diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c')
| -rw-r--r-- | drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c | 191 |
1 files changed, 151 insertions, 40 deletions
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 dada04296025..942d9f0b6df2 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c @@ -51,12 +51,12 @@ */ struct gpio_service *dal_gpio_service_create( - enum dce_version dce_version_major, - enum dce_version dce_version_minor, + enum dce_version dce_version, + enum dce_environment dce_environment, struct dc_context *ctx) { struct gpio_service *service; - uint32_t index_of_id; + int32_t index_of_id; service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL); @@ -65,14 +65,14 @@ struct gpio_service *dal_gpio_service_create( return NULL; } - if (!dal_hw_translate_init(&service->translate, dce_version_major, - dce_version_minor)) { + if (!dal_hw_translate_init(&service->translate, dce_version, + dce_environment)) { BREAK_TO_DEBUGGER(); goto failure_1; } - if (!dal_hw_factory_init(&service->factory, dce_version_major, - dce_version_minor)) { + if (!dal_hw_factory_init(&service->factory, dce_version, + dce_environment)) { BREAK_TO_DEBUGGER(); goto failure_1; } @@ -112,7 +112,7 @@ struct gpio_service *dal_gpio_service_create( return service; failure_2: - while (index_of_id) { + while (index_of_id > 0) { --index_of_id; kfree(service->busyness[index_of_id]); } @@ -128,7 +128,7 @@ struct gpio *dal_gpio_service_create_irq( uint32_t offset, uint32_t mask) { - enum gpio_id id; + enum gpio_id id = 0; uint32_t en; if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) { @@ -139,6 +139,57 @@ 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 = 0; + 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_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 = {0}; + + 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) { @@ -163,6 +214,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. @@ -173,6 +239,9 @@ static bool is_pin_busy( enum gpio_id id, uint32_t en) { + if (id == GPIO_ID_UNKNOWN) + return false; + return service->busyness[id][en]; } @@ -181,6 +250,9 @@ static void set_pin_busy( enum gpio_id id, uint32_t en) { + if (id == GPIO_ID_UNKNOWN) + return; + service->busyness[id][en] = true; } @@ -189,17 +261,50 @@ static void set_pin_free( enum gpio_id id, uint32_t en) { + if (id == GPIO_ID_UNKNOWN) + return; + service->busyness[id][en] = false; } -enum gpio_result dal_gpio_service_open( +enum gpio_result dal_gpio_service_lock( struct gpio_service *service, enum gpio_id id, - uint32_t en, - enum gpio_mode mode, - struct hw_gpio_pin **ptr) + uint32_t en) { - struct hw_gpio_pin *pin; + if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) { + ASSERT_CRITICAL(false); + return GPIO_RESULT_OPEN_FAILED; + } + + set_pin_busy(service, id, en); + return GPIO_RESULT_OK; +} + +enum gpio_result dal_gpio_service_unlock( + struct gpio_service *service, + enum gpio_id id, + uint32_t en) +{ + if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) { + ASSERT_CRITICAL(false); + return GPIO_RESULT_OPEN_FAILED; + } + + set_pin_free(service, id, en); + return GPIO_RESULT_OK; +} + +enum gpio_result dal_gpio_service_open( + struct gpio *gpio) +{ + 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); @@ -213,50 +318,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; } @@ -278,11 +376,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) { @@ -314,6 +411,20 @@ enum dc_irq_source dal_irq_get_rx_source( } } +enum dc_irq_source dal_irq_get_read_request( + const struct gpio *irq) +{ + enum gpio_id id = dal_gpio_get_id(irq); + + switch (id) { + case GPIO_ID_HPD: + return (enum dc_irq_source)(DC_IRQ_SOURCE_DCI2C_RR_DDC1 + + dal_gpio_get_enum(irq)); + default: + return DC_IRQ_SOURCE_INVALID; + } +} + enum gpio_result dal_irq_setup_hpd_filter( struct gpio *irq, struct gpio_hpd_config *config) @@ -346,7 +457,6 @@ struct gpio *dal_gpio_create_irq( case GPIO_ID_GPIO_PAD: break; default: - id = GPIO_ID_HPD; ASSERT_CRITICAL(false); return NULL; } @@ -369,7 +479,6 @@ void dal_gpio_destroy_irq( return; } - dal_gpio_close(*irq); dal_gpio_destroy(irq); kfree(*irq); @@ -558,7 +667,9 @@ enum gpio_result dal_ddc_set_config( void dal_ddc_close( struct ddc *ddc) { - dal_gpio_close(ddc->pin_clock); - dal_gpio_close(ddc->pin_data); + if (ddc != NULL) { + dal_gpio_close(ddc->pin_clock); + dal_gpio_close(ddc->pin_data); + } } |
