summaryrefslogtreecommitdiff
path: root/drivers/video/tegra
diff options
context:
space:
mode:
authorJon Mayo <jmayo@nvidia.com>2014-05-15 17:45:08 -0700
committerEmad Mir <emir@nvidia.com>2014-06-27 19:50:25 -0700
commit58bf883bf47223dc5a45ecf11a331ae01c58700c (patch)
tree7fa0eef49b0d545941536c1c22a15cda2d198c43 /drivers/video/tegra
parent4ece899eefea447d1d732f976c42df9a5589707a (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/tegra')
-rw-r--r--drivers/video/tegra/dc/dc.c60
-rw-r--r--drivers/video/tegra/dc/dc_priv_defs.h2
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;