summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMin-wuk Lee <mlee@nvidia.com>2013-09-06 17:43:06 +0900
committerGabby Lee <galee@nvidia.com>2013-09-10 19:02:19 -0700
commit8a2f117c4472919ec22263c858fbac1a91ee5e72 (patch)
tree5b3c24ad96831464848e70d253e59238cf17d58c /drivers
parentedf22c31968ec0658e1315f9c6d468f3961c9e1e (diff)
tegra: video: hdmi: WAR: ensure hdcp register access with clk enabled
There is a race condition between hdcp upstream and hdmi disable during suspend/resume stress with hdmi plugged-in. WAR by making host1x/hdmi clk enabled and hdmi clk out of reset. Bug 1349507 Change-Id: I6870066358900d6f6798b3e20bc59bf5645f25b8 Original-author: Roger Hsieh <rhsieh@nvidia.com> Signed-off-by: Roger Hsieh <rhsieh@nvidia.com> Signed-off-by: Min-wuk Lee <mlee@nvidia.com> Reviewed-on: http://git-master/r/271389 GVS: Gerrit_Virtual_Submit Reviewed-by: Gabby Lee <galee@nvidia.com> Tested-by: Gabby Lee <galee@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tegra/dc/hdmi.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/drivers/video/tegra/dc/hdmi.c b/drivers/video/tegra/dc/hdmi.c
index ccce7c707f35..0f98cd75acaa 100644
--- a/drivers/video/tegra/dc/hdmi.c
+++ b/drivers/video/tegra/dc/hdmi.c
@@ -109,6 +109,7 @@ struct tegra_dc_hdmi_data {
};
struct tegra_dc_hdmi_data *dc_hdmi;
+atomic_t __maybe_unused tf_hdmi_enable = ATOMIC_INIT(0);
#if defined(CONFIG_ARCH_TEGRA_3x_SOC)
const struct tmds_config tmds_config[] = {
@@ -470,6 +471,34 @@ static inline void tegra_hdmi_hotplug_enable(struct tegra_dc_hdmi_data *hdmi)
enable_irq(gpio_to_irq(dc->out->hotplug_gpio));
}
+void tegra_hdmi_enable_clk(void)
+{
+ struct tegra_dc_hdmi_data *hdmi = dc_hdmi;
+ struct tegra_dc *dc = hdmi->dc;
+
+ mutex_lock(&dc->lock);
+ clk_prepare_enable(hdmi->disp1_clk);
+ clk_prepare_enable(hdmi->disp2_clk);
+ clk_prepare_enable(hdmi->clk);
+ mutex_unlock(&dc->lock);
+ atomic_set(&tf_hdmi_enable, 1);
+}
+EXPORT_SYMBOL(tegra_hdmi_enable_clk);
+
+void tegra_hdmi_disable_clk(void)
+{
+ struct tegra_dc_hdmi_data *hdmi = dc_hdmi;
+ struct tegra_dc *dc = hdmi->dc;
+
+ atomic_set(&tf_hdmi_enable, 0);
+ mutex_lock(&dc->lock);
+ clk_disable_unprepare(hdmi->clk);
+ clk_disable_unprepare(hdmi->disp1_clk);
+ clk_disable_unprepare(hdmi->disp2_clk);
+ mutex_unlock(&dc->lock);
+
+}
+EXPORT_SYMBOL(tegra_hdmi_disable_clk);
#ifdef CONFIG_DEBUG_FS
static int dbg_hdmi_show(struct seq_file *m, void *unused)
@@ -1840,9 +1869,11 @@ static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
clk_set_rate(hdmi->clk, dc->mode.pclk);
clk_prepare_enable(hdmi->clk);
- tegra_periph_reset_assert(hdmi->clk);
- mdelay(1);
- tegra_periph_reset_deassert(hdmi->clk);
+ if (!atomic_read(&tf_hdmi_enable)) {
+ tegra_periph_reset_assert(hdmi->clk);
+ mdelay(1);
+ tegra_periph_reset_deassert(hdmi->clk);
+ }
/* TODO: copy HDCP keys from KFUSE to HDMI */
@@ -2059,7 +2090,6 @@ static void tegra_dc_hdmi_disable(struct tegra_dc *dc)
clk_disable_unprepare(hdmi->hda2codec_clk);
clk_disable_unprepare(hdmi->hda_clk);
#endif
- tegra_periph_reset_assert(hdmi->clk);
hdmi->clk_enabled = false;
clk_disable_unprepare(hdmi->clk);
tegra_dvfs_set_rate(hdmi->clk, 0);