diff options
author | Min-wuk Lee <mlee@nvidia.com> | 2011-06-02 11:03:01 +0900 |
---|---|---|
committer | Rohan Somvanshi <rsomvanshi@nvidia.com> | 2011-06-14 04:29:17 -0700 |
commit | ca3b85f97ea2ffb9a8ed4c4f434ebbc8bfcf2253 (patch) | |
tree | 83024f168a405830f33075fe1c34f9a6e8bf698c | |
parent | bf623c5edbc8f0f5b23d5580aea1038418893792 (diff) |
tegra: dc: fix dc hang during dc reset
1. fix dc hang during dc reset
2. do dc reset after dc clk enabling
in reset worker function
3. remove a few build warnings
Bug 801463
Change-Id: Idc94263084e8a3f83694b30efe09e563ffe64068
Reviewed-on: http://git-master/r/33112
Reviewed-on: http://git-master/r/36231
Reviewed-by: Min-wuk Lee <mlee@nvidia.com>
Tested-by: Min-wuk Lee <mlee@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 80 |
1 files changed, 54 insertions, 26 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index 2fdc8c58ad1f..87b30c0d3177 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -1313,8 +1313,8 @@ static void tegra_dc_set_color_control(struct tegra_dc *dc) static void tegra_dc_init(struct tegra_dc *dc) { - u32 disp_syncpt; - u32 vblank_syncpt; + u32 disp_syncpt = 0; + u32 vblank_syncpt = 0; int i; tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); @@ -1390,8 +1390,57 @@ static bool _tegra_dc_controller_enable(struct tegra_dc *dc) tegra_dc_setup_clk(dc, dc->clk); clk_enable(dc->clk); clk_enable(dc->emc_clk); + + enable_irq(dc->irq); + + tegra_dc_init(dc); + + if (dc->out_ops && dc->out_ops->enable) + dc->out_ops->enable(dc); + + if (dc->out->out_pins) + tegra_dc_set_out_pin_polars(dc, dc->out->out_pins, + dc->out->n_out_pins); + + if (dc->out->postpoweron) + dc->out->postpoweron(); + + /* force a full blending update */ + dc->blend.z[0] = -1; + + return true; +} + +static bool _tegra_dc_controller_reset_enable(struct tegra_dc *dc) +{ + if (dc->out->enable) + dc->out->enable(); + + tegra_dc_setup_clk(dc, dc->clk); + clk_enable(dc->clk); + clk_enable(dc->emc_clk); + + if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) { + mutex_lock(&tegra_dcs[1]->lock); + disable_irq(tegra_dcs[1]->irq); + } else if (dc->ndev->id == 1 && tegra_dcs[0] != NULL) { + mutex_lock(&tegra_dcs[0]->lock); + disable_irq(tegra_dcs[0]->irq); + } + + msleep(5); + tegra_periph_reset_assert(dc->clk); + msleep(2); tegra_periph_reset_deassert(dc->clk); - msleep(10); + msleep(1); + + if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) { + enable_irq(tegra_dcs[1]->irq); + mutex_unlock(&tegra_dcs[1]->lock); + } else if (dc->ndev->id == 1 && tegra_dcs[0] != NULL) { + enable_irq(tegra_dcs[0]->irq); + mutex_unlock(&tegra_dcs[0]->lock); + } enable_irq(dc->irq); @@ -1515,29 +1564,8 @@ static void tegra_dc_reset_worker(struct work_struct *work) _tegra_dc_controller_disable(dc); - if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) { - mutex_lock(&tegra_dcs[1]->lock); - disable_irq(tegra_dcs[1]->irq); - } else if (dc->ndev->id == 1 && tegra_dcs[0] != NULL) { - mutex_lock(&tegra_dcs[0]->lock); - disable_irq(tegra_dcs[0]->irq); - } - - msleep(5); - - tegra_periph_reset_assert(dc->clk); - msleep(2); - - if (dc->ndev->id == 0 && tegra_dcs[1] != NULL) { - enable_irq(tegra_dcs[1]->irq); - mutex_unlock(&tegra_dcs[1]->lock); - } else if (dc->ndev->id == 1 && tegra_dcs[0] != NULL) { - enable_irq(tegra_dcs[0]->irq); - mutex_unlock(&tegra_dcs[0]->lock); - } - - /* _tegra_dc_enable deasserts reset */ - _tegra_dc_controller_enable(dc); + /* _tegra_dc_reset_enable asserts and deasserts reset */ + _tegra_dc_controller_reset_enable(dc); dc->enabled = true; unlock: |