diff options
author | Min-wuk Lee <mlee@nvidia.com> | 2013-09-06 17:43:06 +0900 |
---|---|---|
committer | Gabby Lee <galee@nvidia.com> | 2013-09-10 19:02:19 -0700 |
commit | 8a2f117c4472919ec22263c858fbac1a91ee5e72 (patch) | |
tree | 5b3c24ad96831464848e70d253e59238cf17d58c /drivers | |
parent | edf22c31968ec0658e1315f9c6d468f3961c9e1e (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.c | 38 |
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); |