diff options
author | Jon Mayo <jmayo@nvidia.com> | 2014-05-15 17:45:08 -0700 |
---|---|---|
committer | Emad Mir <emir@nvidia.com> | 2014-06-27 19:50:25 -0700 |
commit | 58bf883bf47223dc5a45ecf11a331ae01c58700c (patch) | |
tree | 7fa0eef49b0d545941536c1c22a15cda2d198c43 /drivers/video | |
parent | 4ece899eefea447d1d732f976c42df9a5589707a (diff) |
video: tegra: dc: skip duplicate CMU update
Skip updating CMU on first boot, and restore CMU after disable or
suspend. Use dc->pdata->cmu_enable to select initial state of cmu, and
move the current cmu status out of dc->pdata and into dc->cmu_enabled.
Remove unused flag TEGRA_DC_FLAG_CMU_ENABLE.
Bug 1507065
Reviewed-on: http://git-master/r/410636
(cherry picked from commit 0c0bfb40e67fb31a01bd69695e0f153dbb2ac8de)
Change-Id: I645923339653698d1be137b3b90ad38735c3159e
Signed-off-by: Jon Mayo <jmayo@nvidia.com>
Reviewed-on: http://git-master/r/431945
Reviewed-by: Mitch Luban <mluban@nvidia.com>
Tested-by: Mitch Luban <mluban@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 60 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_priv_defs.h | 2 |
2 files changed, 37 insertions, 25 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index fc1d80abb3f5..cd5057752e70 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -1091,10 +1091,12 @@ static void tegra_dc_set_scaling_filter(struct tegra_dc *dc) } #ifdef CONFIG_TEGRA_DC_CMU -static void tegra_dc_cache_cmu(struct tegra_dc_cmu *dst_cmu, +static void tegra_dc_cache_cmu(struct tegra_dc *dc, struct tegra_dc_cmu *src_cmu) { - memcpy(dst_cmu, src_cmu, sizeof(struct tegra_dc_cmu)); + if (&dc->cmu != src_cmu) /* ignore if it would require memmove() */ + memcpy(&dc->cmu, src_cmu, sizeof(*src_cmu)); + dc->cmu_dirty = true; } static void tegra_dc_set_cmu(struct tegra_dc *dc, struct tegra_dc_cmu *cmu) @@ -1121,45 +1123,40 @@ static void tegra_dc_set_cmu(struct tegra_dc *dc, struct tegra_dc_cmu *cmu) val = LUT2_ADDR(i) | LUT1_DATA(cmu->lut2[i]); tegra_dc_writel(dc, val, DC_COM_CMU_LUT2); } + + dc->cmu_dirty = false; } -int _tegra_dc_update_cmu(struct tegra_dc *dc, struct tegra_dc_cmu *cmu) +static void _tegra_dc_update_cmu(struct tegra_dc *dc, struct tegra_dc_cmu *cmu) { u32 val; - if (dc->pdata->cmu_enable) { - dc->pdata->flags |= TEGRA_DC_FLAG_CMU_ENABLE; - } else { - dc->pdata->flags &= ~TEGRA_DC_FLAG_CMU_ENABLE; - return 0; - } + if (!dc->cmu_enabled) + return; -#ifdef CONFIG_TEGRA_DC_CMU - if (memcmp(cmu, &dc->cmu, sizeof(struct tegra_dc_cmu))) { - tegra_dc_cache_cmu(&dc->cmu, cmu); + tegra_dc_cache_cmu(dc, cmu); - /* Disable CMU */ + if (dc->cmu_dirty) { + /* Disable CMU to avoid programming it while it is in use */ val = tegra_dc_readl(dc, DC_DISP_DISP_COLOR_CONTROL); if (val & CMU_ENABLE) { val &= ~CMU_ENABLE; - tegra_dc_writel(dc, val, DC_DISP_DISP_COLOR_CONTROL); + tegra_dc_writel(dc, val, + DC_DISP_DISP_COLOR_CONTROL); val = GENERAL_ACT_REQ; tegra_dc_writel(dc, val, DC_CMD_STATE_CONTROL); /*TODO: Sync up with vsync */ mdelay(20); } + dev_dbg(&dc->ndev->dev, "updating CMU cmu_dirty=%d\n", + dc->cmu_dirty); tegra_dc_set_cmu(dc, &dc->cmu); } -#endif - - return 0; } int tegra_dc_update_cmu(struct tegra_dc *dc, struct tegra_dc_cmu *cmu) { - int ret; - mutex_lock(&dc->lock); if (!dc->enabled) { mutex_unlock(&dc->lock); @@ -1168,13 +1165,13 @@ int tegra_dc_update_cmu(struct tegra_dc *dc, struct tegra_dc_cmu *cmu) tegra_dc_get(dc); - ret = _tegra_dc_update_cmu(dc, cmu); + _tegra_dc_update_cmu(dc, cmu); tegra_dc_set_color_control(dc); tegra_dc_put(dc); mutex_unlock(&dc->lock); - return ret; + return 0; } EXPORT_SYMBOL(tegra_dc_update_cmu); @@ -1190,11 +1187,11 @@ static struct tegra_dc_cmu *tegra_dc_get_cmu(struct tegra_dc *dc) void tegra_dc_cmu_enable(struct tegra_dc *dc, bool cmu_enable) { - dc->pdata->cmu_enable = cmu_enable; + dc->cmu_enabled = cmu_enable; tegra_dc_update_cmu(dc, tegra_dc_get_cmu(dc)); } #else -#define tegra_dc_cache_cmu(dst_cmu, src_cmu) +#define tegra_dc_cache_cmu(dc, src_cmu) #define tegra_dc_set_cmu(dc, cmu) #define tegra_dc_update_cmu(dc, cmu) #endif @@ -1411,7 +1408,7 @@ static int tegra_dc_set_out(struct tegra_dc *dc, struct tegra_dc_out *out) * read them, but unfortunately there is no reliable and * flicker-free way to do this! */ - tegra_dc_cache_cmu(&dc->cmu, tegra_dc_get_cmu(dc)); + tegra_dc_cache_cmu(dc, tegra_dc_get_cmu(dc)); #endif } else if (out->n_modes > 0) tegra_dc_set_mode(dc, &dc->out->modes[0]); @@ -2112,7 +2109,7 @@ void tegra_dc_set_color_control(struct tegra_dc *dc) } #ifdef CONFIG_TEGRA_DC_CMU - if (dc->pdata->flags & TEGRA_DC_FLAG_CMU_ENABLE) + if (dc->cmu_enabled) color_control |= CMU_ENABLE; #endif @@ -2646,6 +2643,12 @@ int tegra_dc_restore(struct tegra_dc *dc) static void _tegra_dc_disable(struct tegra_dc *dc) { +#ifdef CONFIG_TEGRA_DC_CMU + /* power down resets the registers, setting to true + * causes CMU to be restored in tegra_dc_init(). */ + dc->cmu_dirty = true; +#endif + if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE) { mutex_lock(&dc->one_shot_lock); cancel_delayed_work_sync(&dc->one_shot_work); @@ -3138,6 +3141,12 @@ static int tegra_dc_probe(struct platform_device *ndev) pm_runtime_set_autosuspend_delay(&ndev->dev, 100); pm_runtime_enable(&ndev->dev); +#ifdef CONFIG_TEGRA_DC_CMU + /* if bootloader leaves this head enabled, then skip CMU programming. */ + dc->cmu_dirty = (dc->pdata->flags & TEGRA_DC_FLAG_ENABLED) == 0; + dc->cmu_enabled = dc->pdata->cmu_enable; +#endif + if (dc->pdata->flags & TEGRA_DC_FLAG_ENABLED) { _tegra_dc_set_default_videomode(dc); dc->enabled = _tegra_dc_enable(dc); @@ -3434,6 +3443,7 @@ static int tegra_dc_resume(struct platform_device *ndev) if (dc->out_ops && dc->out_ops->resume) dc->out_ops->resume(dc); + mutex_unlock(&dc->lock); return 0; diff --git a/drivers/video/tegra/dc/dc_priv_defs.h b/drivers/video/tegra/dc/dc_priv_defs.h index fce904cc1d80..230d8093d196 100644 --- a/drivers/video/tegra/dc/dc_priv_defs.h +++ b/drivers/video/tegra/dc/dc_priv_defs.h @@ -168,6 +168,8 @@ struct tegra_dc { int n_windows; #ifdef CONFIG_TEGRA_DC_CMU struct tegra_dc_cmu cmu; + bool cmu_dirty; + bool cmu_enabled; #endif wait_queue_head_t wq; wait_queue_head_t timestamp_wq; |