#include "link_hpd.h"
#include "gpio_service_interface.h"
bool link_get_hpd_state(struct dc_link *link)
{
if (link->link_enc)
return link->link_enc->funcs->get_hpd_state(link->link_enc);
else
return false;
}
void link_enable_hpd(const struct dc_link *link)
{
if (link->link_enc)
link->link_enc->funcs->enable_hpd(link->link_enc);
}
void link_disable_hpd(const struct dc_link *link)
{
if (link->link_enc)
link->link_enc->funcs->disable_hpd(link->link_enc);
}
void link_enable_hpd_filter(struct dc_link *link, bool enable)
{
if (enable) {
link->is_hpd_filter_disabled = false;
program_hpd_filter(link);
} else {
link->is_hpd_filter_disabled = true;
if (link->link_enc)
link->link_enc->funcs->program_hpd_filter(link->link_enc, 0, 0);
}
}
bool program_hpd_filter(const struct dc_link *link)
{
int delay_on_connect_in_ms = 0;
int delay_on_disconnect_in_ms = 0;
if (link->is_hpd_filter_disabled || !link->link_enc) {
ASSERT(link->link_enc);
return false;
}
switch (link->connector_signal) {
case SIGNAL_TYPE_DVI_SINGLE_LINK:
case SIGNAL_TYPE_DVI_DUAL_LINK:
case SIGNAL_TYPE_HDMI_TYPE_A:
delay_on_connect_in_ms = 500;
delay_on_disconnect_in_ms = 100;
break;
case SIGNAL_TYPE_DISPLAY_PORT:
case SIGNAL_TYPE_DISPLAY_PORT_MST:
delay_on_connect_in_ms = 80;
delay_on_disconnect_in_ms = 0;
break;
case SIGNAL_TYPE_LVDS:
case SIGNAL_TYPE_EDP:
default:
return false;
}
return link->link_enc->funcs->program_hpd_filter(link->link_enc, delay_on_connect_in_ms, delay_on_disconnect_in_ms);
}
struct gpio *link_get_hpd_gpio(struct dc_bios *dcb,
struct graphics_object_id link_id,
struct gpio_service *gpio_service)
{
enum bp_result bp_result;
struct graphics_object_hpd_info hpd_info;
struct gpio_pin_info pin_info;
if (dcb->funcs->get_hpd_info(dcb, link_id, &hpd_info) != BP_RESULT_OK)
return NULL;
bp_result = dcb->funcs->get_gpio_pin_info(dcb,
hpd_info.hpd_int_gpio_uid, &pin_info);
if (bp_result != BP_RESULT_OK) {
return NULL;
}
return dal_gpio_service_create_irq(gpio_service,
pin_info.offset,
pin_info.mask);
}
enum hpd_source_id get_hpd_line(struct dc_link *link)
{
struct gpio *hpd;
enum hpd_source_id hpd_id;
hpd_id = HPD_SOURCEID_UNKNOWN;
if (link->ctx && link->ctx->dce_version <= DCN_VERSION_4_01) {
hpd = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id,
link->ctx->gpio_service);
} else {
hpd = NULL;
}
if (hpd) {
switch (dal_irq_get_source(hpd)) {
case DC_IRQ_SOURCE_HPD1:
hpd_id = HPD_SOURCEID1;
break;
case DC_IRQ_SOURCE_HPD2:
hpd_id = HPD_SOURCEID2;
break;
case DC_IRQ_SOURCE_HPD3:
hpd_id = HPD_SOURCEID3;
break;
case DC_IRQ_SOURCE_HPD4:
hpd_id = HPD_SOURCEID4;
break;
case DC_IRQ_SOURCE_HPD5:
hpd_id = HPD_SOURCEID5;
break;
case DC_IRQ_SOURCE_HPD6:
hpd_id = HPD_SOURCEID6;
break;
default:
BREAK_TO_DEBUGGER();
break;
}
dal_gpio_destroy_irq(&hpd);
}
return hpd_id;
}