video: tegra: dc: force the use of new bandwidth
Jon Mayo [Wed, 20 Jun 2012 20:48:53 +0000 (13:48 -0700)]
During programming of a frame or at frame end, force the use of the new EMC
bandwidth instead of the previous frame's bandwidth.
Moved copy of new_bandwidth out of tegra_dc_set_latency_allowance() to match
the semantics of the rest of tegra_dc_program_bandwidth().

bug 949015

Change-Id: I881f3a2c75f3438e3bbb3208b518f15a4574bc91
Signed-off-by: Jon Mayo <jmayo@nvidia.com>
Reviewed-on: http://git-master/r/110149
Reviewed-by: Automatic_Commit_Validation_User
Tested-by: Daniel Solomon <daniels@nvidia.com>
Reviewed-by: Kevin Huang (Eng-SW) <kevinh@nvidia.com>

drivers/video/tegra/dc/bandwidth.c
drivers/video/tegra/dc/dc.c
drivers/video/tegra/dc/dc_priv.h

index ed5bf6e..5d0e5ee 100644 (file)
@@ -32,8 +32,7 @@ static int use_dynamic_emc = 1;
 
 module_param_named(use_dynamic_emc, use_dynamic_emc, int, S_IRUGO | S_IWUSR);
 
-/* uses the larger of w->bandwidth or w->new_bandwidth, and copies
- * w->new_bandwidth into w->bandwidth */
+/* uses the larger of w->bandwidth or w->new_bandwidth */
 static void tegra_dc_set_latency_allowance(struct tegra_dc *dc,
        struct tegra_dc_win *w)
 {
@@ -73,8 +72,6 @@ static void tegra_dc_set_latency_allowance(struct tegra_dc *dc,
        if (w->idx == 1)
                tegra_set_latency_allowance(vfilter_tab[dc->ndev->id], bw);
 #endif
-
-       w->bandwidth = w->new_bandwidth;
 }
 
 static unsigned int tegra_dc_windows_is_overlapped(struct tegra_dc_win *a,
@@ -220,12 +217,13 @@ void tegra_dc_clear_bandwidth(struct tegra_dc *dc)
  * dc->new_emc_clk_rate into dc->emc_clk_rate.
  * calling this function both before and after a flip is sufficient to select
  * the best possible frequency and latency allowance.
+ * set use_new to true to force dc->new_emc_clk_rate programming.
  */
-void tegra_dc_program_bandwidth(struct tegra_dc *dc)
+void tegra_dc_program_bandwidth(struct tegra_dc *dc, bool use_new)
 {
        unsigned i;
 
-       if (dc->emc_clk_rate != dc->new_emc_clk_rate) {
+       if (use_new || dc->emc_clk_rate != dc->new_emc_clk_rate) {
                /* going from 0 to non-zero */
                if (!dc->emc_clk_rate && !tegra_is_clk_enabled(dc->emc_clk))
                        clk_enable(dc->emc_clk);
@@ -242,8 +240,10 @@ void tegra_dc_program_bandwidth(struct tegra_dc *dc)
        for (i = 0; i < DC_N_WINDOWS; i++) {
                struct tegra_dc_win *w = &dc->windows[i];
 
-               if (w->bandwidth != w->new_bandwidth && w->new_bandwidth != 0)
+               if ((use_new || w->bandwidth != w->new_bandwidth) &&
+                       w->new_bandwidth != 0)
                        tegra_dc_set_latency_allowance(dc, w);
+               w->bandwidth = w->new_bandwidth;
                trace_printk("%s:win%u bandwidth=%d\n", dc->ndev->name, w->idx,
                        w->bandwidth);
        }
index 0b92369..419cd2c 100644 (file)
@@ -1082,7 +1082,7 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
                                msecs_to_jiffies(dc->one_shot_delay_ms));
 
        /* update EMC clock if calculated bandwidth has changed */
-       tegra_dc_program_bandwidth(dc);
+       tegra_dc_program_bandwidth(dc, false);
 
        if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
                update_mask |= NC_HOST_TRIG;
@@ -1489,7 +1489,7 @@ static int tegra_dc_program_mode(struct tegra_dc *dc, struct tegra_dc_mode *mode
 
        /* use default EMC rate when switching modes */
        dc->new_emc_clk_rate = tegra_dc_get_default_emc_clk_rate(dc);
-       tegra_dc_program_bandwidth(dc);
+       tegra_dc_program_bandwidth(dc, true);
 
        tegra_dc_writel(dc, 0x0, DC_DISP_DISP_TIMING_OPTIONS);
        tegra_dc_writel(dc, mode->h_ref_to_sync | (mode->v_ref_to_sync << 16),
@@ -1855,7 +1855,7 @@ static void tegra_dc_vblank(struct work_struct *work)
        /* use the new frame's bandwidth setting instead of max(current, new),
         * skip this if we're using tegra_dc_one_shot_worker() */
        if (!(dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE))
-               tegra_dc_program_bandwidth(dc);
+               tegra_dc_program_bandwidth(dc, true);
 
        /* Clear the V_BLANK_FLIP bit of vblank ref-count if update is clean. */
        if (!tegra_dc_windows_are_dirty(dc))
index a2e77eb..ac3a5d3 100644 (file)
@@ -322,6 +322,6 @@ unsigned int tegra_dc_has_multiple_dc(void);
 
 /* defined in bandwidth.c, used in dc.c */
 void tegra_dc_clear_bandwidth(struct tegra_dc *dc);
-void tegra_dc_program_bandwidth(struct tegra_dc *dc);
+void tegra_dc_program_bandwidth(struct tegra_dc *dc, bool use_new);
 int tegra_dc_set_dynamic_emc(struct tegra_dc_win *windows[], int n);
 #endif