diff options
author | Dave Airlie <airlied@redhat.com> | 2014-06-04 13:39:12 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-06-04 13:39:12 +1000 |
commit | 1c404d88b26170b82aa274e7a40c91aa33145942 (patch) | |
tree | 149e89becf102c010f81bfbe177d9520543ec5f1 /drivers/gpu/drm/msm/hdmi/hdmi_connector.c | |
parent | 04381b987292256db6b8530aad193ee0453b72cd (diff) | |
parent | 543d3011f1c193ba2257a754757117cafda2252b (diff) | |
download | talos-op-linux-1c404d88b26170b82aa274e7a40c91aa33145942.tar.gz talos-op-linux-1c404d88b26170b82aa274e7a40c91aa33145942.zip |
Merge branch 'msm-next' of git://people.freedesktop.org/~robclark/linux into drm-next
Pretty small pull this time around for msm. Adds some useful debugfs
I'd been carrying around on a branch for a while, plus few fixes. And
Kconfig update for the great ARCH_MSM -> ARCH_QCOM split.
* 'msm-next' of git://people.freedesktop.org/~robclark/linux:
drm/msm: use correct gfp flag for vram allocation
drm/msm/mdp5: fix error return value
drm/msm: remove redundant private plane cleanup
drm/msm: add perf logging debugfs
drm/msm: add rd logging debugfs
drm/msm: update for ARCH_MSM -> ARCH_QCOM
drm/msm/hdmi: use gpio and HPD polling
drm/msm/mdp5: fix crash in error/unload paths
Diffstat (limited to 'drivers/gpu/drm/msm/hdmi/hdmi_connector.c')
-rw-r--r-- | drivers/gpu/drm/msm/hdmi/hdmi_connector.c | 52 |
1 files changed, 33 insertions, 19 deletions
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c index 7dedfdd12075..e56a6196867c 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c @@ -247,36 +247,49 @@ void hdmi_connector_irq(struct drm_connector *connector) } } +static enum drm_connector_status detect_reg(struct hdmi *hdmi) +{ + uint32_t hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS); + return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ? + connector_status_connected : connector_status_disconnected; +} + +static enum drm_connector_status detect_gpio(struct hdmi *hdmi) +{ + const struct hdmi_platform_config *config = hdmi->config; + return gpio_get_value(config->hpd_gpio) ? + connector_status_connected : + connector_status_disconnected; +} + static enum drm_connector_status hdmi_connector_detect( struct drm_connector *connector, bool force) { struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector); struct hdmi *hdmi = hdmi_connector->hdmi; - const struct hdmi_platform_config *config = hdmi->config; - uint32_t hpd_int_status; + enum drm_connector_status stat_gpio, stat_reg; int retry = 20; - hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS); + do { + stat_gpio = detect_gpio(hdmi); + stat_reg = detect_reg(hdmi); - /* sense seems to in some cases be momentarily de-asserted, don't - * let that trick us into thinking the monitor is gone: - */ - while (retry-- && !(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED)) { - /* hdmi debounce logic seems to get stuck sometimes, - * read directly the gpio to get a second opinion: - */ - if (gpio_get_value(config->hpd_gpio)) { - DBG("gpio tells us we are connected!"); - hpd_int_status |= HDMI_HPD_INT_STATUS_CABLE_DETECTED; + if (stat_gpio == stat_reg) break; - } + mdelay(10); - hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS); - DBG("status=%08x", hpd_int_status); + } while (--retry); + + /* the status we get from reading gpio seems to be more reliable, + * so trust that one the most if we didn't manage to get hdmi and + * gpio status to agree: + */ + if (stat_gpio != stat_reg) { + DBG("HDMI_HPD_INT_STATUS tells us: %d", stat_reg); + DBG("hpd gpio tells us: %d", stat_gpio); } - return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ? - connector_status_connected : connector_status_disconnected; + return stat_gpio; } static void hdmi_connector_destroy(struct drm_connector *connector) @@ -389,7 +402,8 @@ struct drm_connector *hdmi_connector_init(struct hdmi *hdmi) DRM_MODE_CONNECTOR_HDMIA); drm_connector_helper_add(connector, &hdmi_connector_helper_funcs); - connector->polled = DRM_CONNECTOR_POLL_HPD; + connector->polled = DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT; connector->interlace_allowed = 1; connector->doublescan_allowed = 0; |