summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Wagner <mwagner@nvidia.com>2011-10-10 14:46:55 -0700
committerSimone Willett <swillett@nvidia.com>2011-10-13 12:21:09 -0700
commit555a50c0fe4840d4de41c789bc472cda2902ed31 (patch)
tree9a8078ace03446048ca34e66a03b68daa7f707d0
parenta9277e51d087437f9246fc4824993bf86cda5533 (diff)
video: tegra: Add priorities for DIDIM aggressiveness
Allows DIDIM to keep track of multiple aggressiveness settings based on different priority levels. Four Priority levels are supported and the maximum priority currently specified overrules the other settings. Lowest priority is given to the default kernel value and user specified values. Bug 888292 Change-Id: I970c33bbc662ffd3bf432b4de945abdb604b6895 Reviewed-on: http://git-master/r/57130 Tested-by: Matt Wagner <mwagner@nvidia.com> Reviewed-by: Jon Mayo <jmayo@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/include/mach/dc.h7
-rw-r--r--drivers/video/tegra/dc/dc_reg.h4
-rw-r--r--drivers/video/tegra/dc/nvsd.c62
3 files changed, 61 insertions, 12 deletions
diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h
index 1ac66a6f96b1..21fe93312455 100644
--- a/arch/arm/mach-tegra/include/mach/dc.h
+++ b/arch/arm/mach-tegra/include/mach/dc.h
@@ -254,6 +254,11 @@ struct tegra_dc_sd_rgb {
u8 b;
};
+struct tegra_dc_sd_agg_priorities {
+ u8 pri_lvl;
+ u8 agg[4];
+};
+
struct tegra_dc_sd_settings {
unsigned enable;
bool use_auto_pwm;
@@ -267,6 +272,8 @@ struct tegra_dc_sd_settings {
u16 cur_phase_step;
u16 phase_in_steps;
+ struct tegra_dc_sd_agg_priorities agg_priorities;
+
bool use_vid_luma;
struct tegra_dc_sd_rgb coeff;
diff --git a/drivers/video/tegra/dc/dc_reg.h b/drivers/video/tegra/dc/dc_reg.h
index 43b41cc02398..8d08467731f8 100644
--- a/drivers/video/tegra/dc/dc_reg.h
+++ b/drivers/video/tegra/dc/dc_reg.h
@@ -546,4 +546,8 @@
#define SD_MAN_K_G(x) (((x) & 0x3ff) << 10)
#define SD_MAN_K_B(x) (((x) & 0x3ff) << 20)
+#define NUM_AGG_PRI_LVLS 4
+#define SD_AGG_PRI_LVL(x) ((x) >> 3)
+#define SD_GET_AGG(x) ((x) & 0x7)
+
#endif
diff --git a/drivers/video/tegra/dc/nvsd.c b/drivers/video/tegra/dc/nvsd.c
index 1393a5755d95..33e25a00dad7 100644
--- a/drivers/video/tegra/dc/nvsd.c
+++ b/drivers/video/tegra/dc/nvsd.c
@@ -246,6 +246,46 @@ static bool nvsd_update_enable(struct tegra_dc_sd_settings *settings,
return false;
}
+static bool nvsd_update_agg(struct tegra_dc_sd_settings *settings, int agg_val)
+{
+ int i;
+ int pri_lvl = SD_AGG_PRI_LVL(agg_val);
+ int agg_lvl = SD_GET_AGG(agg_val);
+ struct tegra_dc_sd_agg_priorities *sd_agg_priorities =
+ &settings->agg_priorities;
+
+ if (agg_lvl > 5 || agg_lvl < 0)
+ return false;
+ else if (agg_lvl == 0 && pri_lvl == 0)
+ return false;
+
+ if (pri_lvl >= 0 && pri_lvl < 4)
+ sd_agg_priorities->agg[pri_lvl] = agg_lvl;
+
+ for (i = NUM_AGG_PRI_LVLS - 1; i >= 0; i--) {
+ if (sd_agg_priorities->agg[i])
+ break;
+ }
+
+ sd_agg_priorities->pri_lvl = i;
+ pri_lvl = i;
+ agg_lvl = sd_agg_priorities->agg[i];
+
+ if (settings->phase_in && settings->enable &&
+ settings->aggressiveness != agg_lvl) {
+
+ settings->final_agg = agg_lvl;
+ settings->cmd |= AGG_CHG;
+ settings->cur_agg_step = 0;
+ return true;
+ } else if (settings->aggressiveness != agg_lvl) {
+ settings->aggressiveness = agg_lvl;
+ return true;
+ }
+
+ return false;
+}
+
/* Functional initialization */
void nvsd_init(struct tegra_dc *dc, struct tegra_dc_sd_settings *settings)
{
@@ -270,6 +310,10 @@ void nvsd_init(struct tegra_dc *dc, struct tegra_dc_sd_settings *settings)
dev_dbg(&dc->ndev->dev, "NVSD Init:\n");
+ /* init agg_priorities */
+ if (!settings->agg_priorities.agg[0])
+ settings->agg_priorities.agg[0] = settings->aggressiveness;
+
/* WAR: Settings will not be valid until the next flip.
* Thus, set manual K to either HW's current value (if
* we're already enabled) or a non-effective value (if
@@ -642,20 +686,14 @@ static ssize_t nvsd_settings_store(struct kobject *kobj,
nvsd_check_and_update(0, 1, enable);
}
} else if (IS_NVSD_ATTR(aggressiveness)) {
- if (sd_settings->phase_in && sd_settings->enable) {
- err = strict_strtol(buf, 10, &result);
- if (err)
- return err;
+ err = strict_strtol(buf, 10, &result);
+ if (err)
+ return err;
- if (result > 0 && result <= 5 &&
- result != sd_settings->aggressiveness) {
+ if (nvsd_update_agg(sd_settings, result)
+ && !sd_settings->phase_in)
+ settings_updated = true;
- sd_settings->cmd |= AGG_CHG;
- sd_settings->final_agg = result;
- sd_settings->cur_agg_step = 0;
- }
- } else
- nvsd_check_and_update(1, 5, aggressiveness);
} else if (IS_NVSD_ATTR(phase_in)) {
nvsd_check_and_update(0, 1, phase_in);
} else if (IS_NVSD_ATTR(bin_width)) {