summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2018-03-06 20:57:50 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2018-03-06 20:57:50 -0800
commitdf41a54a67ec6f65fa5aa9a67f24b2d24d772c79 (patch)
tree77136a3c200a0b898bba1937a4db8b5e530a0618
parent99b73ed59a2865a23d0106c4392b6efe31fb5342 (diff)
parent7f85fee1bc725d9bf7f150c8351ede32cd8b4810 (diff)
Merge "drm/msm: HPD_OFF Property for SDE HDMI Connector"
-rw-r--r--drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c50
-rw-r--r--drivers/gpu/drm/msm/hdmi/hdmi.h3
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h3
-rw-r--r--drivers/gpu/drm/msm/sde/sde_connector.c16
-rw-r--r--drivers/gpu/drm/msm/sde/sde_connector.h6
5 files changed, 71 insertions, 7 deletions
diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c
index 3c149f191871..9d7e6f1f14c3 100644
--- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -1215,6 +1215,9 @@ static int _sde_hdmi_gpio_config(struct hdmi *hdmi, bool on)
gpio_free(config->hpd_gpio);
+ if (config->hpd5v_gpio != -1)
+ gpio_free(config->hpd5v_gpio);
+
if (config->mux_en_gpio != -1) {
gpio_set_value_cansleep(config->mux_en_gpio, 0);
gpio_free(config->mux_en_gpio);
@@ -1336,6 +1339,8 @@ static int _sde_hdmi_hpd_enable(struct sde_hdmi *sde_hdmi)
HDMI_HPD_CTRL_ENABLE | hpd_ctrl);
spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+ hdmi->hpd_off = false;
+ SDE_DEBUG("enabled hdmi hpd\n");
return 0;
fail:
@@ -1395,7 +1400,7 @@ int sde_hdmi_core_enable(struct sde_hdmi *sde_hdmi)
return ret;
}
-static void _sde_hdmi_hdp_disable(struct sde_hdmi *sde_hdmi)
+static void _sde_hdmi_hpd_disable(struct sde_hdmi *sde_hdmi)
{
struct hdmi *hdmi = sde_hdmi->ctrl.ctrl;
const struct hdmi_platform_config *config = hdmi->config;
@@ -1403,6 +1408,11 @@ static void _sde_hdmi_hdp_disable(struct sde_hdmi *sde_hdmi)
int i, ret = 0;
unsigned long flags;
+ if (hdmi->hpd_off) {
+ pr_warn("hdmi display hpd was already disabled\n");
+ return;
+ }
+
spin_lock_irqsave(&hdmi->reg_lock, flags);
/* Disable HPD interrupt */
hdmi_write(hdmi, REG_HDMI_HPD_CTRL, 0);
@@ -1429,12 +1439,42 @@ static void _sde_hdmi_hdp_disable(struct sde_hdmi *sde_hdmi)
pr_warn("failed to disable hpd regulator: %s (%d)\n",
config->hpd_reg_names[i], ret);
}
+ hdmi->hpd_off = true;
+ SDE_DEBUG("disabled hdmi hpd\n");
+}
+
+/**
+ * _sde_hdmi_update_hpd_state() - Update the HDMI HPD clock state
+ *
+ * @state: non-zero to disbale HPD clock, 0 to enable.
+ * return: 0 on success, non-zero in case of failure.
+ *
+ */
+static int
+_sde_hdmi_update_hpd_state(struct sde_hdmi *hdmi_display, u64 state)
+{
+ struct hdmi *hdmi = hdmi_display->ctrl.ctrl;
+ int rc = 0;
+
+ if (hdmi_display->non_pluggable)
+ return 0;
+
+ SDE_DEBUG("changing hdmi hpd state to %llu\n", state);
+
+ if (state == SDE_MODE_HPD_ON) {
+ if (!hdmi->hpd_off)
+ pr_warn("hdmi display hpd was already enabled\n");
+ rc = _sde_hdmi_hpd_enable(hdmi_display);
+ } else
+ _sde_hdmi_hpd_disable(hdmi_display);
+
+ return rc;
}
void sde_hdmi_core_disable(struct sde_hdmi *sde_hdmi)
{
/* HPD contains all the core clock and pwr */
- _sde_hdmi_hdp_disable(sde_hdmi);
+ _sde_hdmi_hpd_disable(sde_hdmi);
}
static void _sde_hdmi_cec_update_phys_addr(struct sde_hdmi *display)
@@ -2204,6 +2244,8 @@ int sde_hdmi_set_property(struct drm_connector *connector,
rc = _sde_hdmi_enable_pll_update(display, value);
else if (property_index == CONNECTOR_PROP_PLL_DELTA)
rc = _sde_hdmi_update_pll_delta(display, value);
+ else if (property_index == CONNECTOR_PROP_HPD_OFF)
+ rc = _sde_hdmi_update_hpd_state(display, value);
return rc;
}
@@ -2281,7 +2323,7 @@ int sde_hdmi_connector_pre_deinit(struct drm_connector *connector,
return -EINVAL;
}
- _sde_hdmi_hdp_disable(sde_hdmi);
+ _sde_hdmi_hpd_disable(sde_hdmi);
return 0;
}
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 8ca7b36ee0c8..9a0733bf81ff 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -50,6 +50,9 @@ struct hdmi {
const struct hdmi_platform_config *config;
+ /* hpd state: */
+ bool hpd_off;
+
/* audio state: */
struct hdmi_audio audio;
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 25dc5f9ef561..fb24b833082c 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -164,6 +164,7 @@ enum msm_mdp_conn_property {
CONNECTOR_PROP_TOPOLOGY_NAME,
CONNECTOR_PROP_TOPOLOGY_CONTROL,
CONNECTOR_PROP_LP,
+ CONNECTOR_PROP_HPD_OFF,
/* total # of properties */
CONNECTOR_PROP_COUNT
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index 6a741a7ce0f6..e8dfd1f08236 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -46,6 +46,11 @@ static const struct drm_prop_enum_list e_power_mode[] = {
{SDE_MODE_DPMS_OFF, "OFF"},
};
+static const struct drm_prop_enum_list hpd_clock_state[] = {
+ {SDE_MODE_HPD_ON, "ON"},
+ {SDE_MODE_HPD_OFF, "OFF"},
+};
+
int sde_connector_get_info(struct drm_connector *connector,
struct msm_display_info *info)
{
@@ -475,6 +480,9 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
_sde_connector_update_power_locked(c_conn);
mutex_unlock(&c_conn->lock);
break;
+ case CONNECTOR_PROP_HPD_OFF:
+ c_conn->hpd_mode = val;
+ break;
default:
break;
}
@@ -819,6 +827,7 @@ struct drm_connector *sde_connector_init(struct drm_device *dev,
c_conn->display = display;
c_conn->dpms_mode = DRM_MODE_DPMS_ON;
+ c_conn->hpd_mode = SDE_MODE_HPD_ON;
c_conn->lp_mode = 0;
c_conn->last_panel_power_mode = SDE_MODE_DPMS_ON;
@@ -946,6 +955,11 @@ struct drm_connector *sde_connector_init(struct drm_device *dev,
ARRAY_SIZE(e_power_mode),
CONNECTOR_PROP_LP, 0);
+ msm_property_install_enum(&c_conn->property_info, "HPD_OFF",
+ DRM_MODE_PROP_ATOMIC, 0, hpd_clock_state,
+ ARRAY_SIZE(hpd_clock_state),
+ CONNECTOR_PROP_HPD_OFF, 0);
+
rc = msm_property_install_get_status(&c_conn->property_info);
if (rc) {
SDE_ERROR("failed to create one or more properties\n");
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.h b/drivers/gpu/drm/msm/sde/sde_connector.h
index 0f563ac25da8..7db98afad713 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.h
+++ b/drivers/gpu/drm/msm/sde/sde_connector.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -22,6 +22,9 @@
#include "sde_kms.h"
#include "sde_fence.h"
+#define SDE_MODE_HPD_ON 0
+#define SDE_MODE_HPD_OFF 1
+
#define SDE_CONNECTOR_NAME_SIZE 16
struct sde_connector;
@@ -207,6 +210,7 @@ struct sde_connector {
struct sde_fence retire_fence;
struct sde_connector_ops ops;
int dpms_mode;
+ u64 hpd_mode;
int lp_mode;
int last_panel_power_mode;