summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Gilling <konkers@android.com>2010-09-27 16:49:38 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:35:46 -0800
commit4828081ac345914be97964af2eed0de8c4bb8138 (patch)
tree871f5f1e954bb59c3e7f55f6fe7d0303cb981dff
parent584212afe54bf5568886a0a6f5b96ce1b5f17182 (diff)
video: tegra: enable both display controller clock when enabling hdmi
The upstream DC needs to be clocked for accesses to HDMI to not hard lock the system. Because we don't know if HDMI is conencted to disp1 or disp2 we need to enable both until we set the DC mux. Change-Id: Iab7df9911aa9034ea559896850787e4eff3237d7 Signed-off-by: Erik Gilling <konkers@android.com>
-rw-r--r--drivers/video/tegra/dc/hdmi.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/drivers/video/tegra/dc/hdmi.c b/drivers/video/tegra/dc/hdmi.c
index 1906d086d666..844d2a44f6de 100644
--- a/drivers/video/tegra/dc/hdmi.c
+++ b/drivers/video/tegra/dc/hdmi.c
@@ -49,6 +49,9 @@ struct tegra_dc_hdmi_data {
struct resource *base_res;
void __iomem *base;
struct clk *clk;
+
+ struct clk *disp1_clk;
+ struct clk *disp2_clk;
};
const struct fb_videomode tegra_dc_hdmi_supported_modes[] = {
@@ -475,7 +478,9 @@ static int tegra_dc_hdmi_init(struct tegra_dc *dc)
struct resource *res;
struct resource *base_res;
void __iomem *base;
- struct clk *clk;
+ struct clk *clk = NULL;
+ struct clk *disp1_clk = NULL;
+ struct clk *disp2_clk = NULL;
int err;
hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
@@ -510,6 +515,20 @@ static int tegra_dc_hdmi_init(struct tegra_dc *dc)
goto err_iounmap_reg;
}
+ disp1_clk = clk_get_sys("tegradc.0", NULL);
+ if (IS_ERR_OR_NULL(disp1_clk)) {
+ dev_err(&dc->ndev->dev, "hdmi: can't disp1 clock\n");
+ err = -ENOENT;
+ goto err_put_clock;
+ }
+
+ disp2_clk = clk_get_sys("tegradc.1", NULL);
+ if (IS_ERR_OR_NULL(disp2_clk)) {
+ dev_err(&dc->ndev->dev, "hdmi: can't disp2 clock\n");
+ err = -ENOENT;
+ goto err_put_clock;
+ }
+
/* TODO: support non-hotplug */
if (request_irq(gpio_to_irq(dc->out->hotplug_gpio), tegra_dc_hdmi_irq,
IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
@@ -533,6 +552,8 @@ static int tegra_dc_hdmi_init(struct tegra_dc *dc)
hdmi->base = base;
hdmi->base_res = base_res;
hdmi->clk = clk;
+ hdmi->disp1_clk = disp1_clk;
+ hdmi->disp2_clk = disp2_clk;
tegra_dc_set_outdata(dc, hdmi);
@@ -541,7 +562,12 @@ static int tegra_dc_hdmi_init(struct tegra_dc *dc)
err_free_irq:
free_irq(gpio_to_irq(dc->out->hotplug_gpio), dc);
err_put_clock:
- clk_put(clk);
+ if (!IS_ERR_OR_NULL(disp2_clk))
+ clk_put(disp2_clk);
+ if (!IS_ERR_OR_NULL(disp1_clk))
+ clk_put(disp1_clk);
+ if (!IS_ERR_OR_NULL(clk))
+ clk_put(clk);
err_iounmap_reg:
iounmap(base);
err_release_resource_reg:
@@ -560,6 +586,8 @@ static void tegra_dc_hdmi_destroy(struct tegra_dc *dc)
iounmap(hdmi->base);
release_resource(hdmi->base_res);
clk_put(hdmi->clk);
+ clk_put(hdmi->disp1_clk);
+ clk_put(hdmi->disp2_clk);
tegra_edid_destroy(hdmi->edid);
kfree(hdmi);
@@ -792,6 +820,13 @@ static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
bool dvi = false;
/* enbale power, clocks, resets, etc. */
+
+ /* The upstream DC needs to be clocked for accesses to HDMI to not
+ * hard lock the system. Because we don't know if HDMI is conencted
+ * to disp1 or disp2 we need to enable both until we set the DC mux.
+ */
+ clk_enable(hdmi->disp1_clk);
+ clk_enable(hdmi->disp2_clk);
tegra_dc_setup_clk(dc, hdmi->clk);
clk_set_rate(hdmi->clk, dc->mode.pclk);
@@ -834,6 +869,9 @@ static void tegra_dc_hdmi_enable(struct tegra_dc *dc)
ARM_VIDEO_RANGE_LIMITED,
HDMI_NV_PDISP_INPUT_CONTROL);
+ clk_disable(hdmi->disp1_clk);
+ clk_disable(hdmi->disp2_clk);
+
dispclk_div_8_2 = clk_get_rate(hdmi->clk) / 1000000 * 4;
tegra_hdmi_writel(hdmi,
SOR_REFCLK_DIV_INT(dispclk_div_8_2 >> 2) |